Привязка не обновляется, как ожидалось - PullRequest
3 голосов
/ 06 сентября 2010

Я создаю простой UserControl , DoubleDatePicker , который определяет DependencyProperty , SelectedDate :

DoubleDatePicker.xaml :

<UserControl x:Class="TestWpfDoubleDatePicker.DoubleDatePicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit">    
<StackPanel x:Name="LayoutRoot" Background="White">
    <toolkit:DatePicker x:Name="DateInput" SelectedDate="{Binding SelectedDate,Mode=TwoWay}" Margin="5,0,5,0" />
    <TextBlock Text="{Binding SelectedDate}" />
    <toolkit:DatePicker SelectedDate="{Binding SelectedDate,Mode=TwoWay}" Margin="5,0,5,0" />
</StackPanel>

DoubleDatePicker.xaml.cs :

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


namespace TestWpfDoubleDatePicker
{
    public partial class DoubleDatePicker : UserControl
    {
        public static readonly DependencyProperty SelectedDateProperty =
        DependencyProperty.Register("SelectedDate", typeof(DateTime), typeof(DoubleDatePicker), null);

        public DateTime SelectedDate
        {
            get { return (DateTime)this.GetValue(SelectedDateProperty); }
            set { this.SetValue(SelectedDateProperty, value); }
        }

        public DoubleDatePicker()
        {
            this.InitializeComponent();

            this.DataContext = this;
        }
    }
}

Я бы хотел иметь возможность связывать свойство SelectedDate извне, но все не так просто. Вот пример кода, который пытается получить значение свойства в TextBlock :

MainWindow.xaml :

<Window x:Class="TestWpfDoubleDatePicker.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestWpfDoubleDatePicker"
    Title="MainWindow" Height="350" Width="525">
<StackPanel x:Name="LayoutRoot" Background="White">
    <local:DoubleDatePicker x:Name="ddp" SelectedDate="{Binding SelectedDate}" />
    <Button Content="Update" Click="Button_Click" />
    <TextBlock Text="{Binding SelectedDate}" />
</StackPanel>

и MainWindow.xaml.cs :

using System;
using System.Windows;

namespace TestWpfDoubleDatePicker
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public static readonly DependencyProperty SelectedDateProperty =
            DependencyProperty.Register("SelectedDate", typeof(DateTime), typeof(MainWindow), null);

        public DateTime SelectedDate
        {
            get { return (DateTime)this.GetValue(SelectedDateProperty); }
            set { this.SetValue(SelectedDateProperty, value); }
        }

        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = this;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            this.SelectedDate = this.ddp.SelectedDate;
        }
    }
}

Внутри самого DoubleDatePicker все работает нормально: свойство SelectedDate обновляется при изменении с использованием любого из двух DatePicker и TextBlock из DoubleDatePicker обновляется как ожидалось.

Но снаружи TextBlock MainWindow не обновляется автоматически и является единственным способом получить свойство SelectedDate DoubleDatePicker - получить его явно, как это делается при нажатии кнопки .

Что я делаю не так?

Я использую Visual Studio Professional 2010 с WPF 4.

Заранее спасибо за помощь.

1 Ответ

5 голосов
/ 06 сентября 2010

То, что вы делаете неправильно, перезаписывает ваш DataContext внутри вашего элемента управления следующим образом:

this.DataContext = this;

Теперь ваш DatePicker больше не привязывается к намеченному объекту, а вместо этого привязывается к вашему экземпляру DatePicker.Я предполагаю, что это не то, как вы предполагали, что ваш DatePicker будет работать;).

Итак, удалите эту строку в вашем DatePicker, и если вам нужно связать внутри XAML вашего DatePicker, используйте ElementName или RelativeSource привязки для привязки к этому свойству зависимости.

Надеюсь, это прояснит ситуацию;)

Я позволил себе переписать ваши привязки внутри вашего XAML вашего DatePicker, используя привязки ElementName:

<UserControl x:Class="TestWpfDoubleDatePicker.DoubleDatePicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit" 
x:Name="Root">    
<StackPanel x:Name="LayoutRoot" Background="White">
    <toolkit:DatePicker x:Name="DateInput" SelectedDate="{Binding ElementName=Root, Path=SelectedDate,Mode=TwoWay}" Margin="5,0,5,0" />
    <TextBlock Text="{Binding ElementName=Root, Path=SelectedDate}" />
    <toolkit:DatePicker SelectedDate="{Binding ElementName=Root, Path=SelectedDate,Mode=TwoWay}" Margin="5,0,5,0" />
</StackPanel>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...