簡體   English   中英

WPF 自定義控件構造、觸發器和事件

[英]WPF Custom Controls Construction,Triggers and Events

我想構建一個新的自定義控件。 我發現很少有教程可以讓我了解如何實現這一目標。 據我了解,創建新的自定義控件總是通過擴展當前控件來完成的,甚至可以從層次結構的非常基本的級別擴展控件,例如,您甚至可以擴展:

  • 用戶界面元素
  • 框架元素
  • 控制
  • 內容控制
  • 標題內容控件
  • 項目控制
  • 選擇器
  • 范圍基礎

如以下教程中所寫: http : //wpftutorial.net/HowToCreateACustomControl.html

所以,我按照教程創建了一個自定義控件庫類型的新項目,得到了我的通用 .xaml 和我的代碼。 到現在為止還挺好。

我可以區分 3 種類型或類別的事件。

  1. 由將使用我的控件的窗口(或容器)消耗的事件:這些是我想向外部公開的事件。 這些怎么寫?

  2. 與控件本身相關且未暴露於外部的事件; 例如,如果鼠標懸停在我的控制上方,而我想對此做出反應。 我可以在 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”怎么辦?

  1. 與子元素相關的事件,這些子元素是我的 ControlTemplate 的可視化結構的一部分,例如,如果我想對 XAML/甚至代碼隱藏中的“LeftTraigularIndicator”的“IsMouseOver”做出反應怎么辦? 甚至可能兩者兼而有之。

我現在正在嘗試 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM