如何为绑定创建依赖属性

时间:2017-06-06 14:52:19

标签: c# wpf data-binding dependency-properties

我在"简单"案件。我想创建一个实现DependencyProperty的新自定义控件。在下一步中,我想创建一个绑定来更新两个方向的属性。我为这个案例建立了一个简单的样本,但绑定似乎不起作用。我已经找到了使用FrameworkPropertyMetadata更新DPControl属性的方法,但我不知道使用OnPropertyChanged事件是否也是个好主意。

这是我的示例项目:

我的控件只包含一个标签

<UserControl x:Class="WPF_MVVM_ListBoxMultiSelection.DPControl"
             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:local="clr-namespace:WPF_MVVM_ListBoxMultiSelection"
             mc:Ignorable="d" Height="84.062" Width="159.641">
    <Grid Margin="0,0,229,268">
        <Label Content="TEST" x:Name="label" Margin="0,0,-221,-102"/>
    </Grid>
</UserControl>

并实现自定义依赖项属性。目前,我还为FramePropertyMetadata实现了PropertyChanged方法,并在此方法中设置了标签的内容,但我希望它能在两个方向上运行。

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

    public string MyCustomLabelContent
    {
        get { return (string)GetValue(MyCustomLabelContentProperty);}
        set
        {
            SetValue(MyCustomLabelContentProperty, value);
        }
    }

    private static void OnMyCustomLabelContentPropertyChanged(DependencyObject source,
    DependencyPropertyChangedEventArgs e)
    {
        DPControl control = (DPControl)source;
        control.label.Content = e.NewValue;
    }

    public static readonly DependencyProperty MyCustomLabelContentProperty = DependencyProperty.Register(
          "MyCustomLabelContent",
          typeof(string),
          typeof(DPControl),
          new FrameworkPropertyMetadata(null,
              OnMyCustomLabelContentPropertyChanged
          )
        );

我只是在一个Window中使用这个控件:

<local:DPControl MyCustomLabelContent="{Binding MyLabelContent, Mode=TwoWay}" Margin="72,201,286,34"/>

MyLabelContent是ViewModel中的一个属性,它还实现了INotifyPropertyChanged接口。

public class ViewModel_MainWindow:NotifyPropertyChanged
{

    private string _myLabelContent;

    public string MyLabelContent
    {
        get { return _myLabelContent; }
        set { _myLabelContent = value;
            RaisePropertyChanged();
        }
    }...

那么我怎样才能使它工作:在自定义属性上使用我的新控件的绑定功能。

1 个答案:

答案 0 :(得分:3)

在您的UserControl中:

<Label 
    Content="{Binding MyCustomLabelContent, RelativeSource={RelativeSource AncestorType=UserControl}}"
    x:Name="label" Margin="0,0,-221,-102"/>

摆脱那个属性改变的回调。所有你需要的是绑定。

  

我喜欢双向工作

默认情况下,将依赖项属性设置为双向:

public static readonly DependencyProperty MyCustomLabelContentProperty = 
    DependencyProperty.Register(
        "MyCustomLabelContent",
        typeof(string),
        typeof(DPControl),
        new FrameworkPropertyMetadata(null, 
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
    );

我省略了不必要的属性更改处理程序。

现在它不是双向的,因为Label.Content无法生成自己的值。如果您希望UserControl在其代码隐藏中设置值,那很简单:

MyCustomLabelContent = "Some arbitrary value";

如果你像我给你的那样进行了绑定,那将更新UserControl XAML中的Label以及绑定到UserControl的依赖属性的viewmodel属性。

如果您想让XAML进行设置,您需要

最后,这个:

Margin="0,0,-221,-102"

不是做布局的好方法。使用GridStackPanel等的WPF布局更容易,更健壮。