Привязка к пользовательским зависимым свойствам из XAML - PullRequest
3 голосов
/ 02 ноября 2011

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

3 голосов
/ 02 ноября 2011

Делать , а не установить DataContext = this; на UserControls, таким образом все привязки в экземплярах завершатся неудачно, если вы предполагаете, что DataContext наследуется, так как это останавливает его и также совершенно невидимо. В привязках UserControl вы должны либо назвать элемент управления и выполнить ElementName привязок, либо использовать RelativeSource.

1010 *, например *

<UserControl Name="control" ...>
     <TextBlock Text="{Binding Text, ElementName=control}"/>
<UserControl ...>
     <TextBlock Text="{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
0 голосов
/ 02 ноября 2011

Дайте вашему окну имя и измените привязку на следующую: (в противном случае используется datacontext из 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>

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

НТН

...