C# WPF自定义控件构造、触发器和事件

C# WPF自定义控件构造、触发器和事件,c#,.net,wpf,wpf-controls,custom-controls,C#,.net,Wpf,Wpf Controls,Custom Controls,我想构建一个新的自定义控件。我发现很少有教程给了我一些如何实现这一点的线索。据我所知,创建新的自定义控件总是通过扩展当前控件来完成的,甚至可以扩展 例如,您甚至可以从层次结构的最基本级别扩展控件: UIElement 框架元件 控制 内容控制 头部内容控制 项目控制 选择器 牧场基地 如以下教程所述: 因此,我按照教程创建了一个新的自定义控件库类型的项目,保留了我的generic.xaml和代码。到目前为止还不错 我可以区分3种类型或类别的事件 将使用我的控件的窗口(或容器)可以使用的事件:

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

  • UIElement
  • 框架元件
  • 控制
  • 内容控制
  • 头部内容控制
  • 项目控制
  • 选择器
  • 牧场基地
如以下教程所述:

因此,我按照教程创建了一个新的自定义控件库类型的项目,保留了我的generic.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>  
    
    
    
  • 假设我有一个元素在我的 名为x:name=“LeftTraingularIndicator”的ControlTemplate

    问题:

    现在我想在我的XAML中对IsMouseDown做出反应。我该怎么做? 没有“IsMouseDown”触发器。此外,如果我想要呢 在代码背后对它做出反应?更进一步,如果我想要呢 要从代码隐藏更改LeftTraingularIndicator“Fill”吗

  • 与作为可视对象一部分的子元素相关的事件 我的ControlTemplate的构造,在示例中,如果我想做出反应,该怎么办 在XAML中或甚至在代码隐藏中使用“LeftTraigularIndicator”的“IsMouseOver”? 也许两者都有
  • 我已经尝试了两天了。。。感觉我在理解事物如何运作时遗漏了一些东西。没有找到任何能深入解释这些问题的教程

    我想为我在这里提出的每一个问题看几行例子


    谢谢。

    经过广泛的研究

    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.直接的

    如果将事件定义为冒泡事件(本质上),则该事件将从源冒泡到其容器。例如:如果一个网格有两个按钮-矩形1和矩形2,那么点击这些矩形就会进入网格。隧道与此相反,事件通过隧道从父级传递到子级

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

    你的问题:

    将使用我的控件的窗口(或容器)可以使用的事件:这些是我希望对外公开的事件。。怎么写

    您基本上需要编写一个冒泡事件。下面是msdn中的一个示例,用于在按钮上编写冒泡点击事件(我自己没有尝试过):

    你的问题:

    问题:现在我想在我的XAML中对IsMouseDown做出反应。。。我该怎么做?没有“IsMouseDown”触发器。。更进一步,如果我想在代码背后对此做出反应,该怎么办?更进一步,如果我想从后面的代码中更改LeftTraingularIndicator“Fill”,该怎么办

    顺便说一句,您似乎对事件和触发器有些混淆(因为我看到您可以互换使用它们)。虽然它们是相关的,但它们并不相同

    回到你的问题——WPF允许在属性更改上触发——这就是你本质上要挂接的内容——在本例中,IsMouseOver。但是缺少的是属性是ControlTemplate的目标(我不知道它是什么)。我只是推断ControlTemplate的目标是一个矩形。在这种情况下,它没有“IsMouseDown”属性供您钩住属性触发器。这就是你找不到它的原因。另一个选项是您必须编写一个AttachedEvent(它们与AttachedProperties非常相似)。。另一个主题是:(


    我希望我尽了最大努力:)

    我喜欢你的回答,因为它进一步阐明了这个主题,特别是关于事件方向的问题,但是在尝试构建新的自定义控件时,我试图将重点放在XAML和代码隐藏之间的联系上。当你用漂亮的形状创建XAML,2分钟后,你开始意识到你没有办法为这些项目提供功能,我相信很多人都喜欢这堵墙。命名部件是唯一将功能链接到XAML的部件,但它不是intui
    public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
    "Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple));