WPF自定义控件
我想构建一个新的自定义控件 . 我发现很少的教程给了我一些如何实现这一目标的线索 . 据我了解,创建一个新的自定义控件总是通过扩展当前控件来完成,甚至可以从层次结构的最基本级别扩展控件,例如,您甚至可以扩展:
-
UIElement
-
FrameworkElement
-
控制
-
ContentControl
-
HeaderedContentControl
-
ItemsControl
-
选择器
-
RangeBase
如以下教程中所述: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”,还有什么呢?
- 与子元素相关的事件,这些子元素是我的ControlTemplate的可视化构造的一部分,例如,如果我想对XAML中的"LeftTraigularIndicator"的"LeftTraigularIndicator"做出反应,甚至是在Code Behind中?也许两者都有 .
我现在正在尝试2天......感觉我在理解事情如何运作时遗漏了一些东西 . 没有找到任何深入解释这些问题的教程 .
我希望看到我在这里提出的每个问题的几行例子 .
谢谢 .
2 回答
经过广泛研究......
1)将事件暴露给外部......就像你从任何其他阶级暴露出来一样 .
在你的代码中的某个地方:
那部分没什么新东西 .
2)从后面的代码创建一个实例构造函数
3)不推荐 - 因为它属于用户控件的范围而不是自定义控件 . 自定义控件是“原子”,用户控件更适合组合控件的目的 .
但并非不可能......
请记住:
必须在代码隐藏中找到任何应该知道的内容 .
你的xaml应该不知道背后的代码是做什么的 . (除了! - 继续阅读)
在设计XAML时,代码隐藏中应该知道的部件必须具有正确的名称 .
我真的希望这会帮助那些在尝试开发自己的自定义控件时获得“墙”的人 .
如果我理解你的问题 - 以下是我的解释 .
WPF事件系统提供3种类型的事件:1 . 冒泡2.隧道3.直接
如果事件(在内部)被定义为冒泡事件,则事件将从源传递到其容器 . 例如:如果Grid有两个按钮 - Rectangle1和Rectangle2,那么对这些矩形的任何点击都会向上冒泡到Grid . 隧道是相反的,事件从父母隧道到孩子 .
直接活动非常特别 - 它们仅适用于没有意义的活动 . 例如,在上面的场景中,在任一个矩形上冒泡MouseOver事件都没有意义 - 因为每次鼠标进入矩形时,事件都会冒泡到网格 - 这是人们可能期望的 .
你的问题:
你基本上需要写一个冒泡事件 . 下面是一个msdn的例子,用于在Button上写一个冒泡的tap事件(我自己没试过)Routed event example:
你的问题:
顺便说一下,你似乎对事件和触发器有些混淆(因为我看到你可以互换使用它们) . 虽然它们是相关的,但它们并不相同 .
回到你的问题 - WPF允许触发属性更改 - 这实际上就是你要挂钩的 - 在这种情况下是IsMouseOver . 但缺少的是该属性是ControlTemplate的目标(我不知道它是什么) . 我只是推断ControlTemplate的目标是一个Rectangle . 在这种情况下,它没有“IsMouseDown”属性来挂钩属性触发器 . 这就是你无法找到它的原因 . 另一个选项你必须写一个AttachedEvent(它们与AttachedProperties非常相似)..另一个话题:(
我希望我尽我所能:)