绑定到XAML的自定义Depenendy属性

时间:2011-11-02 09:22:11

标签: wpf xaml dependency-properties inotifypropertychanged

我已经实现了一个自定义DependencyProperty,并希望从XAML绑定到它。由于某种原因,更新绑定源(MainWindow.Test)时不会更新。 绑定源不是DP但会触发PropertyChanged事件。 但是,更新适用于非自定义依赖项属性

作品

<TextBlock Text="{Binding Test}" />

不起作用

<local:DpTest Text="{Binding Test}"/>

有什么想法吗?


以下是DP实施

using System;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication3
{
public partial class DpTest : UserControl
{
    public DpTest()
    {
        DataContext = this;
        InitializeComponent();
    }

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(DpTest), new PropertyMetadata(string.Empty, textChangedCallBack));

    static void textChangedCallBack(DependencyObject property, DependencyPropertyChangedEventArgs args)
    {
        int x = 5;
    }
}
}

以下是它的使用方法:

<Window x:Class="WpfApplication3.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:local="clr-namespace:WpfApplication3" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="MainWindow" Height="350" Width="525">
<StackPanel>
    <TextBlock Text="{Binding Test}"></TextBlock>
    <local:DpTest Text="{Binding Test}"></local:DpTest>
    <Button Click="Button_Click">Update</Button>
</StackPanel></Window>

绑定来源的代码:

using System;
using System.Collections.Generic;
using System.Windows;
using System.ComponentModel;

namespace WpfApplication3
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        DataContext = this;
        InitializeComponent();
    }
    string _test;
    public string Test
    {
        get { return _test; }
        set
        {
            _test = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("Test"));
            }
        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Test = "Updatet Text";
    }
    public event PropertyChangedEventHandler PropertyChanged;
}
}

2 个答案:

答案 0 :(得分:3)

DataContext = this;设置UserControls,如果您假设要继承DataContext,那么实例上的所有绑定都会失败,因为这会阻止它也很隐蔽。在UserControl绑定中,您应该为控件命名并执行ElementName绑定或使用RelativeSource

e.g。

<UserControl Name="control" ...>
     <TextBlock Text="{Binding Text, ElementName=control}"/>
<UserControl ...>
     <TextBlock Text="{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}}"/>

答案 1 :(得分:0)

为您的窗口命名并将绑定更改为以下内容: (否则使用UserControl的datacontext,这不是你想要的)

...
x:Name="mainWindow">
        <Grid>
        <StackPanel>
          <TextBlock Height="20" Background="Yellow" Text="{Binding Test}"></TextBlock>
          <local:DpTest Text="{Binding Path=Test, ElementName=mainWindow, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></local:DpTest>
          <Button Click="Button_Click">Update</Button>

在你的UserControl中没有绑定,然后按以下方式绑定:

<TextBlock Text="{Binding ElementName=dpTest, Path=Text,
Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBlock>

这对我有用..

HTH