绑定未按预期更新

Pra*_*eek 3 c# data-binding wpf binding user-controls

我正在构建一个简单的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>
Run Code Online (Sandbox Code Playgroud)

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望能够从外部绑定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>
Run Code Online (Sandbox Code Playgroud)

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

里面DoubleDatePicker本身所有工作的罚款:在SelectedDate时,通过使用任何两个改变属性更新的DatePickerTextBlock中的的DoubleDatePicker按预期进行更新.

但是,外面的TextBlock中的的主窗口不会自动更新,并获得唯一的办法SelectedDate的财产DoubleDatePicker是让它明确,喜欢它点击时的完成按钮.

我究竟做错了什么 ?

我正在使用带有WPF 4的Visual Studio Professional 2010.

在此先感谢您的帮助.

Arc*_*rus 5

你做错了是用你的方法覆盖你的控件中的DataContext:

this.DataContext = this;
Run Code Online (Sandbox Code Playgroud)

现在,您的DatePicker不再绑定到您的目标对象,而是绑定到您的DatePicker实例.我想这不是你希望你的DatePicker工作的方式;).

因此,在DatePicker中删除该行,如果确实需要在DatePicker的XAML中绑定,请使用ElementNameRelativeSource绑定绑定到此依赖项属性.

希望这能澄清事情;)

我冒昧地使用ElementName绑定在您的DatePicker的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" 
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>
Run Code Online (Sandbox Code Playgroud)