Привязка к пользовательскому свойству Depenendy из XAML

Я реализовал пользовательское свойство 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;
}
}

person Christoph    schedule 02.11.2011    source источник
comment
Вы проверяли наличие ошибок привязки в окне вывода?   -  person Thomas Levesque    schedule 02.11.2011


Ответы (2)


Не не устанавливайте 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}}"/>
person H.B.    schedule 02.11.2011

Дайте вашему окну имя и измените привязку на следующее: (в противном случае используется контекст данных UserControl, а это не то, что вы хотите в вашем случае)

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

это сработало для меня..

ХТН

person SvenG    schedule 02.11.2011