【问题标题】:Custom dependency property binding自定义依赖属性绑定
【发布时间】:2013-10-16 06:44:21
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# wpf properties dependencies


    【解决方案1】:

    您应该在 SomeUserControl 中使用 ElementName 绑定。

    <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。 Data Binding in WPF User Controls

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 没有。那是行不通的。控制模板中的绑定是正确的。因为如果我在没有绑定的情况下为“MyTest”赋值,那么 Control 工作正常。无法从其他地方进行外部绑定。但我认为在 ControlTemplate 级别上没问题。
      • 我的错.. 没有看到您明确将子用户控件的数据上下文设置为自身.. 更新的答案应该可以工作
      • 它工作正常。谢谢)但是是否可以避免RelativeSource声明?
      • 在这个场景中,你必须告诉绑定在哪里寻找源代码,因为默认总是在它的 DataContext 中查找
      猜你喜欢
      • 2012-08-07
      • 1970-01-01
      • 2012-08-29
      • 2013-06-20
      • 2011-12-20
      • 2011-04-11
      • 2012-12-07
      • 1970-01-01
      相关资源
      最近更新 更多