如何绑定自定义控件

时间:2018-10-03 21:42:00

标签: wpf

在WPF应用程序中,我做了自己的控件,并希望绑定到其中的属性。这是我到目前为止尝试过的:

public partial class BreadcrumbContainer : Grid
{
    public static readonly DependencyProperty TestProperty =
    DependencyProperty.Register(nameof(Test), typeof(string), typeof(BreadcrumbContainer), new PropertyMetadata(string.Empty));

    public string Test
    {
        get { return (string)GetValue(TestProperty); }
        set { SetValue(TestProperty, value); Refresh(); }
    }

    public BreadcrumbContainer()
    {
        InitializeComponent();
    }

    private void Refresh()
    {
        // never gets called
    }
}

然后我尝试像这样绑定到我的Test属性:

<controls:BreadcrumbContainer Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Test="{Binding SearchMessage}"/>

在我的视图模型中,我有一个属性SearchMessage。我所有其他的绑定都正常工作,所以肯定是我在BreadcrumbContainer

中做错了

1 个答案:

答案 0 :(得分:3)

引用亚当·内森(Adam Nathan)发布的WPF

  

.NET属性包装在设置时在运行时被绕过   XAML中的依赖项属性。尽管XAML编译器取决于   属性包装器在编译时,WPF调用基础   直接在运行时获取GetValue和SetValue方法!

您所用的属性包装器是您的Test属性。因此,基本上,不要在其中放置任何逻辑,因为它永远不会在运行时被调用。正确的方法是使用属性更改的回调。答案found here为您提供了一个示例。请注意DependencyProperty.Register调用中的回调初始化。

Checklist for Defining a Dependency Property 中还有“官方”文档-实施“包装器”

  

在除特殊情况外的所有情况下,包装器实现应分别仅执行GetValue和SetValue操作。主题XAML Loading and Dependency Properties中将讨论其原因。

来自XAML Loading and Dependency Properties

  

由于针对属性设置的XAML处理器行为的当前WPF实现完全绕过了包装器,因此您不应为自定义依赖项属性在包装器的集合定义中添加任何其他逻辑。如果将这样的逻辑放在集合定义中,则当在XAML中而不是在代码中设置属性时,将不会执行该逻辑。

这是WPF中令人困惑的行为的一个示例,如果您不知道,它将使您发疯。这并不是您的错,但我建议阅读Adam Nathan撰写的WPF Unleashed-和所有在线文档,以了解有关这些陷阱的更多信息。