簡體   English   中英

WPF UserControl:在綁定多個控件中的一個屬性后不返回setter

[英]WPF UserControl: setter not called on binding one property in multiple controls and back

我的WPF UserControl在多個控件中綁定一個屬性並返回時遇到問題。 業務對象的設置器將不會被調用。 我現在搜索了幾個小時,並嘗試了無法解決的問題。

我的密碼

可以在這里下載: WpfApplicationUserControlProblem.zip

我的業務對象有2個要綁定的DateTime值。

public class BusinessObject
{
    private DateTime _value1 = DateTime.Today.AddHours(10);
    public DateTime Value1
    {
        get { return _value1; }
        set { _value1 = value; }        // will never be called but why??
    }

    private DateTime _value2 = DateTime.Today.AddDays(1).AddHours(15);
    public DateTime Value2
    {
        get { return _value2; }
        set { _value2 = value; }        // will never be called but why??
    }
}

我的主窗口有2個用戶控件來綁定對象的2個值

<Window x:Class="WpfApplicationUserControlProblem.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplicationUserControlProblem"
    mc:Ignorable="d"
    Title="MainWindow" Height="120.961" Width="274.489">
<Grid>
    <local:DateTimeUserControl DateTimeValue="{Binding Value1, UpdateSourceTrigger=PropertyChanged}" Margin="10,10,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="241"/>
    <local:DateTimeUserControl DateTimeValue="{Binding Value2, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="10,39,0,0" VerticalAlignment="Top" Width="241"/>
</Grid>

public partial class MainWindow : Window
{
    private BusinessObject _businessObject = new BusinessObject();
    public MainWindow()
    {
        InitializeComponent();
        DataContext = _businessObject;
    }
}

我的UserControl DateTimeUserControl具有一個DependencyProperty“ DateTimeValue”,用於從主窗口接收綁定的業務值。 通過“ DateTimeValuePropertyChangedCallback”,將接收到的值重定向到DatePicker的DateValue和HourTextBox的HourValue中。 更改DatePicker或HourTextBox應該更新DependencyProperty“ DateTimeValue”,因此也將更新有界業務對象。 那是我的計划。

<UserControl x:Class="WpfApplicationUserControlProblem.DateTimeUserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:WpfApplicationUserControlProblem"
         x:Name="_this"
         mc:Ignorable="d">
<Grid>
    <DatePicker SelectedDate="{Binding Path=DateValue, ElementName=_this, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Margin="0,0,61,0"/>
    <TextBox Text="{Binding Path=HourValue, ElementName=_this, UpdateSourceTrigger=PropertyChanged}" Height="24" VerticalAlignment="Top" HorizontalAlignment="Right" Width="56"/>
</Grid>

public partial class DateTimeUserControl : UserControl, INotifyPropertyChanged
{
    public DateTimeUserControl()
    {
        InitializeComponent();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public static readonly DependencyProperty DateTimeValueProperty = DependencyProperty.Register(nameof(DateTimeValue), typeof(DateTime), typeof(DateTimeUserControl), new PropertyMetadata(DateTimeValuePropertyChangedCallback));
    public DateTime DateTimeValue
    {
        get { return (DateTime)GetValue(DateTimeValueProperty); }
        set { SetValue(DateTimeValueProperty, value); }
    }

    private static void DateTimeValuePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        DateTimeUserControl control = d as DateTimeUserControl;
        control.FirePropertyChanged(d, new PropertyChangedEventArgs(nameof(DateValue)));
        control.FirePropertyChanged(d, new PropertyChangedEventArgs(nameof(HourValue)));
    }

    private void FirePropertyChanged(object sender, PropertyChangedEventArgs args)
    {
        PropertyChanged?.Invoke(sender, args);
    }

    public DateTime DateValue
    {
        get { return DateTimeValue.Date; }
        set { DateTimeValue = value.Date.AddHours(DateTimeValue.Hour); }
    }

    public string HourValue
    {
        get { return DateTimeValue.Hour.ToString(); }
        set { DateTimeValue = DateTimeValue.Date.AddHours(int.Parse(value)); }
    }
}

我不明白

除了在更新DependencyProperty時不調用業務對象的setter之外,其他所有東西似乎都工作正常。 但為什么? 我還嘗試了DependencyProperties或MultiBindingConverters進行的所有操作。 我每次嘗試都失敗了。

有人可以幫忙嗎?

DateTimeValue Bindings應該聲明為TwoWay ,而UpdateSourceTrigger=PropertyChanged當然是多余的:

<local:DateTimeUserControl DateTimeValue="{Binding Value1, Mode=TwoWay}" .../>

您還可以聲明您的DateTimeValue依賴項屬性以默認方式雙向綁定:

public static readonly DependencyProperty DateTimeValueProperty =
    DependencyProperty.Register(
        nameof(DateTimeValue),
        typeof(DateTime),
        typeof(DateTimeUserControl),
        new FrameworkPropertyMetadata(
            default(DateTime),
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
            DateTimeValuePropertyChangedCallback));

您可能會問,為什么在UserControl的XAML中的兩個“內部”綁定上也BindsTwoWayByDefault ,但是DatePicker.SelectedDateTextBox.Text屬性都已經向BindsTwoWayByDefault注冊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM