首页 > 解决方案 > 如何为 FrameworkElement VisualCollection 创建绑定

问题描述

我需要在 WPF 中绘制一些具有命中测试功能的图表。按照文档中的说明,我将几何图形绘制为 DrawingVisuals,并为它们实现了一个主机容器,如下所示(为简洁起见,跳过命中测试代码):

public class MyVisualHost : FrameworkElement
{
    public VisualCollection children;

    public MyVisualHost()
    {
        children = new VisualCollection(this);
    }
    protected override int VisualChildrenCount
    {
        get { return children.Count; }
    }
    protected override Visual GetVisualChild(int index)
    {
        if (index < 0 || index >= children.Count)
            throw new ArgumentOutOfRangeException();
        return children[index];
    }
}

并像这样在xaml中使用它

<local:MyVisualHost/>

用户可以缩放和滚动图表,并且 DrawingVisuals 在单独的线程中更新,不会阻塞 UI。

如何为children属性定义绑定,以便可以在运行时更改它(更新其中包含的 DrawingVisuals)?

更新 我刚刚注意到,当您在 xaml 编辑器中选择 xaml 元素时,“属性”面板中会列出 VisualCollection 属性。我试过为它定义绑定,但它说:

无法在“...MyVisualHost...”类型的“VisualCollection”属性上设置“绑定”。只能在 DependencyObject 的 DependencyProperty 上设置“绑定”

标签: c#wpfgraphicsdrawing

解决方案


首先,您将需要容器上的一些公共属性...

public class MyVisualHost : FrameworkElement
{
    public VisualCollection children;

    public MyVisualHost()
    {
        children = new VisualCollection(this);
        children.Add(new Button() {Name = "button"});
        children.Add(new TextBox() {Name = "textbox"});
    }
    protected override int VisualChildrenCount
    {
        get { return children.Count; }
    }
    protected override Visual GetVisualChild(int index)
    {
        if (index < 0 || index >= children.Count)
            throw new ArgumentOutOfRangeException();
        return children[index];
    }

    public int Count => VisualChildrenCount;
    public Visual this[int index]
    {
        get { return GetVisualChild(index); }
    }
}

接下来像这样在 XAML 中定义它......

<Window.Resources>
    <local:MyVisualHost x:Key="MyVisualHost"/>
</Window.Resources>

最后绑定到这样的属性...

    <TextBox Text="{Binding Path=Count, Source={StaticResource MyVisualHost}, Mode=OneWay}"/>
    <TextBox Text="{Binding Path=[0].Name, Source={StaticResource MyVisualHost}, Mode=OneWay}"/>

推荐阅读