[英]WPF Custom Controls Construction,Triggers and Events
我想構建一個新的自定義控件。 我發現很少有教程可以讓我了解如何實現這一目標。 據我了解,創建新的自定義控件總是通過擴展當前控件來完成的,甚至可以從層次結構的非常基本的級別擴展控件,例如,您甚至可以擴展:
如以下教程中所寫: http : //wpftutorial.net/HowToCreateACustomControl.html
所以,我按照教程創建了一個自定義控件庫類型的新項目,得到了我的通用 .xaml 和我的代碼。 到現在為止還挺好。
我可以區分 3 種類型或類別的事件。
由將使用我的控件的窗口(或容器)消耗的事件:這些是我想向外部公開的事件。 這些怎么寫?
與控件本身相關且未暴露於外部的事件; 例如,如果鼠標懸停在我的控制上方,而我想對此做出反應。 我可以在 XAML 中做到這一點:
<ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Fill" TargetName="LeftTraingularIndicator"> <Setter.Value> <SolidColorBrush Color="Yellow" /> </Setter.Value> </Setter> </Trigger> </ControlTemplate.Triggers>
假設我的 ControlTemplate 中有一個帶有 fill 屬性的元素,名為 x:name="LeftTraingularIndicator"
問題:
現在我想在我的 XAML 中對 IsMouseDown 做出反應。 我怎么做? 沒有“IsMouseDown”觸發器。 此外,如果我想對后面的代碼做出反應怎么辦? 更進一步,如果我想從后面的代碼中更改 LeftTraingularIndicator“Fill”怎么辦?
我現在正在嘗試 2 天......感覺我在理解事物的運作方式時缺少一些東西。 沒有找到任何深入解釋這些問題的教程。
對於我在這里提出的每個問題,我想看到幾行示例。
謝謝。
經過廣泛的研究...
1) 向外界公開事件......就像你從任何其他班級公開一樣。
public delegate void myDelegate(int someValue);
public event myDelegate myEvent;
並在您的代碼中的某處:
if(myEvent!=null)
myEvent(5);
那部分沒有什么新東西。
2)從后面的代碼創建一個實例構造函數
public MyCustomControl()
{
MouseMove += MyCustomControl_MouseMove;
}
void MyCustomControl_MouseMove(object sender, MouseEventArgs e)
{
//now you can react to the movement of the mouse.
//if for example I want to address an element, let's say a rectangle:
var ele = (Rectangle)Template.FindName("myRect",this);
ele.Fill=myNewBrush;
// provided that we have an element named "myRect" (x:name="myRect") in
// the generic.xaml style->Control Template-> which corresponds to that name.
}
3) 不推薦 - 因為它屬於用戶控件的范圍而不是自定義控件。 自定義控件是“原子”,用戶控件更適合組合控件的目的。
但並非不可能...
var myButton = (Button)Template.FindName("myButton",this);
myButton.OnMouseMove += ....
請記住:
任何應該在代碼隱藏中知道的東西都必須被命名。
您的 xaml 應該不知道背后的代碼是做什么的。 (除了! - 繼續閱讀)
在設計 XAML 時,代碼隱藏中應該知道的部分必須具有正確的名稱。
我真的希望這能幫助那些在嘗試開發自己的自定義控件時遇到“牆”的人。
如果我正確理解了您的問題 - 以下是我的解釋。
WPF 事件系統提供 3 種類型的事件:1. 冒泡 2. 隧道 3. 直接
如果一個事件(本質上)被定義為冒泡事件,則該事件從源冒泡到其容器。 例如:如果一個 Grid 有兩個按鈕 - Rectangle1 和 Rectangle2,那么對這些矩形的任何點擊都會向上冒泡到 Grid。 隧道是相反的,事件從父到子隧道。
有一些非常特殊的直接事件 - 它們僅適用於事件沒有意義冒泡的情況。 例如,在上面的場景中,在任一矩形上冒泡 MouseOver 事件是沒有意義的 - 因為每次鼠標進入矩形時,事件都會冒泡到 Grid - 這可能是人們所期望的。
你的問題:
由將使用我的控件的窗口(或容器)消耗的事件:這些是我想向外部公開的事件..如何編寫這些事件?
你基本上需要寫一個冒泡事件。 下面是來自 msdn 的示例,用於在按鈕上編寫冒泡點擊事件(我自己沒有嘗試過)路由事件示例:
public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
"Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple));
你的問題:
問題:現在我想在我的 XAML 中對 IsMouseDown 做出反應……我該怎么做? 沒有“IsMouseDown”觸發器……如果我想對后面的代碼做出反應,該怎么辦? 如果我想從后面的代碼中更改 LeftTraingularIndicator "Fill" 怎么辦?
順便說一句,您似乎對事件和觸發器有些困惑(因為我看到您可以互換使用它們)。 雖然它們是相關的,但它們並不相同。
回到您的問題 - WPF 允許觸發屬性更改 - 在這種情況下,這基本上是您要掛鈎的 - IsMouseOver。 但是缺少的是該屬性是 ControlTemplate 的目標(我不知道它是什么)。 我只是推斷 ControlTemplate 的目標是一個矩形。 在這種情況下,它沒有“IsMouseDown”屬性供您掛鈎屬性觸發器。 這就是你找不到它的原因。 您必須編寫一個 AttachedEvent 的另一個選項(它們與 AttachedProperties 非常相似)...完全是另一個主題:(
我希望我盡力了:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.