自定义依赖属性绑定

4

我有一个关于自定义依赖属性绑定的问题。 我们有: 一个自定义用户控件,具有一个依赖属性,并绑定到自身:

<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>

...和控制代码:

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); }
    }
}

我正在尝试将此控件与简单模型类的某些简单属性绑定使用:

<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>

...带有代码

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

...和模型:

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));
    }
}

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

6
你应该在你的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>

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


2

您需要像下面这样更新绑定,即必须使用RelativeSource绑定到祖先 UserControl 属性,因为您显式设置了子 UserControl 的 DataContext,默认绑定将在子 UserControl 的 DataContext 中搜索路径。

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

不行。控件模板中的绑定是正确的。因为如果我在没有绑定的情况下给"MyTest"赋值,那么控件就能正常工作。但是从另一个地方进行的外部绑定却无法正常工作。但我认为在控件模板层面上一切都没问题。 - kirilljk
我的错..没有注意到你在显式设置子用户控件的数据上下文为它本身..更新后的答案应该可以工作。 - Nitin
可以了,谢谢。但是有没有可能避免使用RelativeSource声明? - kirilljk
在这种情况下,您将不得不告诉绑定程序在哪里查找源,因为默认情况下它总是在其DataContext内部查找。 - Nitin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接