wpf 自定义依赖属性绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19263030/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:48:51  来源:igfitidea点击:

Custom dependency property binding

c#wpfpropertiesdependencies

提问by kirilljk

I got some problem with custom dependency property binding. We have: Custom user control with one dependency property and binding to self:

我在自定义依赖属性绑定方面遇到了一些问题。我们有: 具有一个依赖属性并绑定到 self 的自定义用户控件:

<UserControl x:Class="WpfApplication1.SomeUserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
<Grid>
    <Label>
        <Label.Template>
            <ControlTemplate>
                <Label Content="{Binding MyTest}"/>
            </ControlTemplate>
        </Label.Template>
    </Label>
</Grid>

... and code of control:

...和控制代码:

public partial class SomeUserControl : UserControl
{
    public SomeUserControl()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty MyTestProperty = DependencyProperty.Register("MyTest", typeof(int), typeof(SomeUserControl));

    public int MyTest
    {
        get { return (int)GetValue(MyTestProperty); }
        set { SetValue(MyTestProperty, value); }
    }
}

I trying to use this control with binding to some simple property of simple model class:

我尝试使用此控件绑定到简单模型类的一些简单属性:

<UserControl x:Class="WpfApplication1.AnotherUserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:wpfApplication1="clr-namespace:WpfApplication1"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <wpfApplication1:SomeUserControl MyTest="{Binding Path=Model.MyNum}" Grid.Column="0"/>
    <Label Content="{Binding Path=Model.MyNum}" Grid.Column="1"/>
</Grid>

... with code

...用代码

public partial class AnotherUserControl : UserControl
{
    public MyModel Model { get; set; }
    public AnotherUserControl()
    {
        Model = new MyModel();
        Model.MyNum = 1231;
        InitializeComponent();
    }
}

... and model:

...和型号:

public class MyModel:INotifyPropertyChanged
{
    private int _myNum;

    public int MyNum
    {
        get { return _myNum; }
        set { _myNum = value; OnPropertyChanged("MyNum");}
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

But binding is not working. Stack have no errors in compilation. Now, binding working with statndart wpf label control (with same model), and don't working with my custom control and custom property. Please help me to understand reasons of this problem and solve it; Thanks)

但是绑定不起作用。堆栈在编译时没有错误。现在,绑定使用 statndart wpf 标签控件(具有相同的模型),并且不使用我的自定义控件和自定义属性。请帮我了解这个问题的原因并解决它;谢谢)

回答by blindmeis

You should use ElementName Binding in your SomeUserControl.

您应该在SomeUserControl.

<UserControl x:Class="WpfApplication1.SomeUserControl"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300" 
     x:Name="uc">

<Grid>
    <Label>
        <Label.Template>
            <ControlTemplate>
                <Label Content="{Binding MyTest, ElementName=uc}"/>
            </ControlTemplate>
        </Label.Template>
    </Label>
</Grid>

here some more information why you should not set the datacontext of a usercontrol to self/this. Data Binding in WPF User Controls

这里有更多信息为什么你不应该将用户控件的数据上下文设置为 self/this。 WPF 用户控件中的数据绑定

回答by Nitin

You will need to update your binding as below i.e you will have to bind to the ancestor usercontrol property using RelativeSource as you are setting the DataContext of child usercontrol explicitly, default binding will search for path inside the child userControl's DataContext.

您将需要如下更新您的绑定,即您必须使用 RelativeSource 绑定到祖先用户控件属性,因为您正在显式设置子用户控件的数据上下文,默认绑定将搜索子用户控件的数据上下文中的路径。

        <wpfApplication1:SomeUserControl MyTest="{Binding Path=DataContext.Model.MyNum, RelativeSource={RelativeSource FindAncestor={x:Type UserControl}}}" Grid.Column="0"/>