WPF自定义控件构造,触发器和事件

问题描述:

WPF自定义控件WPF自定义控件构造,触发器和事件

我想构建一个新的自定义控件。我发现很少的教程给了我一些关于如何实现这一点的线索。据我所知,创建一个新的自定义控件总是通过扩展当前控件来完成的,甚至可以从层次结构的基本级别扩展控件,例如,甚至可以扩展:

  • 的UIElement
  • FrameworkElement的
  • 控制
  • ContentControl中
  • HeaderedContentControl
  • 的ItemsControl
  • 选择
  • RangeBase

写在下面的教程:http://wpftutorial.net/HowToCreateACustomControl.html

所以,我也跟着教程和创造型自定义控件库的一个新的项目,得到了我的通用的.xaml和我的代码背后。到现在为止还挺好。

有三种类型或类别的事件我可以区分。

  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中被命名为X的元素:

问题NAME = “LeftTraingularIndicator”:

现在我想在我的XAML中对IsMouseDown做出反应。我怎么做? 没有“IsMouseDown”触发器。此外,如果我想让 对后面的代码做出反应呢?甚至更进一步如果我想要 将LeftTraingularIndicator“Fill”从后面的代码改成什么?

  1. 该相关如果我想在反应“LeftTraigularIndicator”的 为“IsMouseOver”什么子元件,其是视觉 施工我的ControlTemplate的一部分,例如,在活动XAML /甚至在代码隐藏? 也许甚至两个。
  2. 我现在正在尝试2天...感觉我错过了我对事物工作原理的理解。没有找到任何深入解释这些问题的教程。

    我希望看到我在这里提出的每个问题的几行例子。

    谢谢。

开始=“3”>

经过广泛的研究...

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时,代码隐藏中应该知道的部分必须使用正确的名称。

我真的希望这将帮助其他人谁得到了“墙”,试图发展 自己的定制控件时。

+0

你唯一不能与用户控件做将它们用作窗口基类。这使得编写窗口模板非常痛苦。 – rookie1024 2016-07-01 17:35:09

+0

对于3,如果您在Generic.xaml中应用了模板,则可以通过重写'OnApplyTemplate()'来获取任何命名的部分,因为只有包含部分的模板已经设置,才会运行该模板。 – Lauraducky 2017-12-20 00:02:40

如果我正确理解你的问题 - 下面是我的解释。

WPF事件系统提供3种类型的事件: 1.鼓泡 2.隧道 3.直接

如果事件被定义(intrensically)作为冒泡事件,则该事件被从冒泡来源到它的容器。例如:如果一个网格有两个按钮 - Rectangle1和Rectangle2,那么点击这些矩形就会冒泡到网格中。隧道是相反的,事件从父母到孩子隧道。

有直接事件是非常特殊的 - 它们只适用于事件没有意义的情况下冒泡。例如,在上面的场景中,在任何一个矩形上冒泡MouseOver事件都没有任何意义 - 因为每当鼠标进入矩形时,事件就会冒泡到网格 - 这是人们可能期望的。

你的问题:

活动是由窗口(或容器),将用我的控制耗材:这些都是我想暴露于外。该事件怎么写的?

你基本上需要写一个冒泡事件。下面是从MSDN的例子写上一个按钮冒泡敲击事件(我还没有尝试过我自己)Routed event example

public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
"Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple)); 

你的问题:

问题:现在我想反应我XAML到IsMouseDown ...我该怎么做?没有“IsMouseDown”触发器..更多更多如果我想对后面的代码做出反应,该怎么办?甚至更进一步怎么样,如果我想从背后的代码改变LeftTraingularIndicator“填充”?

顺便说一句,你似乎有一些与事件和触发器混淆(因为我看你可以交替使用它们)。尽管它们是相关的,但它们并不相同。

回到你的问题 - WPF允许属性更改的触发器 - 这就是本质上你所关注的 - IsMouseOver在这种情况下。但缺少的是该属性是ControlTemplate的目标(我不知道它是什么)。我只是推断ControlTemplate的目标是一个矩形。在这种情况下,它没有“IsMouseDown”属性来挂钩属性触发器。这就是你无法找到它的原因。你必须写一个AttachedEvent其他选项(它们是非常相似的AttachedProperties)..整体另一个话题:(

我希望尽我所能:)

+0

我喜欢你的答案,因为它进一步阐明了关于事件方向的主题espicailly,但是当试图构建新的自定义控件时,我试图关注XAML和代码隐藏之间的联系。当你创建带有美丽形状的XAML时,很大的一面是,而2分钟后你开始意识到你无法为这些项目提供功能,我相信很多人进入了这个墙。命名的部分是唯一将功能链接到XAML的东西,但它并不直观,因为没有人希望XAML仍然需要知道背后的代码。 – 2013-02-20 06:31:23