设计模式 - WPF 自动将 AttachedProperty 添加到父级
我创建了一个自定义用户控件,它是某种虚拟键盘按钮。我正在寻找以下功能:
- 任何面板都应该包含所有键盘按钮子项的集合。
- 任何其他也是该面板子级的控件都应该能够枚举其父级的键盘按钮。
从功能上实现这一点并不是什么大问题。我可以创建 List 类型的 Attached-DependencyProperty 并手动管理此列表。这种方法的问题是,它很容易出错并且不方便。
是否有可能在创建时自动将键盘按钮附加到父级的 AttachedProperty ?
I've created a custom UserControl which is some kind of virtual keyboard button. I'm looking for the following functionally:
- Any Panel should contain a collection of all it's keyboard button childs.
- Any other control which is also a child of this Panel should be able to enumerate the keyboard buttons of his parent.
It isn't the big problem to achieve this functionally. I could create an Attached-DependencyProperty of type List and manually manage this list. The problem about this approach would be, that it's pretty error prone and inconvenient.
Is there any possibility to automatically attach the keyboard button at creation time to the AttachedProperty of the parent?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如您所提到的,维护列表很容易出错 - 您需要使其与 WPF 可视化树保持同步。您可以从给定的根遍历可视化树,而不是维护列表。就您而言,听起来根是一个
Panel
。遍历视觉树非常容易。 这篇文章展示了一些示例。我认为相关的是这个:
这对给定 DependencyObject 的所有 Visual Children 进行深度优先遍历。因此,对于任何给定的
Panel
,您都可以调用此方法。由于它是IEnumerable
,因此您可以使用 LINQ 将结果筛选到自定义 UserControl。对于您的其他要求(“也是此面板的子级的任何其他控件应该能够枚举其父级的键盘按钮”):给定
Panel
的子级,向上遍历可视化树找到第一个Panel
并使用相同的过程来获取所有相关的子项。如果您确实需要将其作为
DependencyProperty
(例如用于数据绑定),我认为您可以将其设置为只读,并仍然在 getter 中使用 Visual Tree Traversal 方法,但我不确定。As you mentioned, maintaining a list is error-prone - you would need to keep it in sync with the WPF Visual Tree. Instead of maintaining a list, you can traverse the Visual Tree from a given root. In your case, it sounds like the root is a
Panel
.Traversing the Visual Tree is pretty easy. This post shows some examples. The one I think is relevant is this one:
This does a depth-first traversal of all the Visual Children of a given
DependencyObject
. So for any givenPanel
, you can call this method. Since it'sIEnumerable
, you can use LINQ to filter the results to your custom UserControl.For your other requirement ("Any other control which is also a child of this Panel should be able to enumerate the keyboard buttons of his parent"): Given a child of a
Panel
, walk the Visual Tree upwards to find the firstPanel
and use the same process to get all the relevant children.If you really need this as a
DependencyProperty
(e.g. for databinding), I think you could make it readonly and still use the Visual Tree Traversal method in the getter, but I'm not sure.我已经为我的问题创建了一个非常好的解决方案。以下代码显示了我的实现:
我通常不使用 .NET 进行编程,但有时我“被迫”用它创建一些工具。然而,你们中的一些人可能知道我如何消除此代码的一个弱点:它不支持 VisualStudio 或 Expression Blend Designer。因此,控件在设计时无法修改,甚至无法查看。
I've already created a quite good solution for my problem. The following code shows my implementation:
I'm generally not programming in .NET, but - from time to time - I'm "forced" to create some tools with it. However, some of you guys may know how I can remove a weakness of this code: It doesn't support the VisualStudio or Expression Blend Designer. Thus, the controls cannot be modified or even seen at design-time.