在PropertyChanged中WPF TwoWay绑定更改值

时间:2014-03-24 02:06:27

标签: c# wpf binding dependency-properties two-way-binding

我有一个WPF应用程序,在这个应用程序中,我创建了一个自定义UserControl。此Control可以从XML加载定义的Layout。我想在UserControl上有一个BOOL DependencyProperty,我可以设置为true,然后它会加载所需的布局。另外我想通过在完成时将其设置回False来“清除”此标志。本质上,我试图在PropertyChanged处理程序中更改依赖属性的值。

此示例不会随时将属性更新回false。在我的实际应用程序中,它首次将触发器设置为True,但在此之后再也不会。我有一种感觉,因为它在PropertyChanged期间运行LoadTrigger = false NOT。

主要表格

<Window x:Class="WPF_Test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WPF_Test"
    Title="MainWindow" Height="350" Width="525">
<Grid>

    <CheckBox IsChecked="{Binding TriggerToLoad}"></CheckBox>

    <local:UC LoadTrigger="{Binding TriggerToLoad}"></local:UC>

    </Grid>
</Window>

主要表格 - 背后的代码

public partial class MainWindow : Window
{
    private TestViewModel VM;

    public MainWindow()
    {
        InitializeComponent();

        this.VM = new TestViewModel();

        this.DataContext = this.VM;

    }
}

用户控制 - 代码背后

public partial class UC : UserControl
{

    public static readonly DependencyProperty LoadTriggerProperty = DependencyProperty.Register("LoadTrigger", typeof(bool), typeof(UC), new  FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, LoadTriggerPropertyChanged));


    public bool LoadTrigger
    {
        get { return (bool)GetValue(LoadTriggerProperty); }
        set { this.SetValue(LoadTriggerProperty, value); }
    }

    private static void LoadTriggerPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
        {
            ((UC)source).LoadLayout();
        }
    }

    private void LoadLayout()
    {
        MessageBox.Show("Loading the layout now and then setting DependencyProperty back to false.");

        // TRIED THIS
        this.LoadTrigger = false;

        //TRIED THIS TOO
        //this.SetValue(LoadTriggerProperty, false);

        //TRIED THIS TOO
        //this.SetCurrentValue(LoadTriggerProperty, false);

        //TRIED THIS TOO
        //BindingOperations.GetBindingExpression(this, UC.LoadTriggerProperty).UpdateSource();
    }

    public UC()
    {
        InitializeComponent();
    }
}

视图模型

 class TestViewModel : INotifyPropertyChanged
 {



    private bool triggerToLoad;

    public bool TriggerToLoad
    {
        get
        {
            return this.triggerToLoad;
        }

        set
        {
            if (this.triggerToLoad != value)
            {
                this.triggerToLoad = value;
                this.OnPropertyChanged("TriggerToLoad");
            }
        }
    }


    public TestViewModel()
    {
        this.TriggerToLoad = true;
    }



    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if (!object.ReferenceEquals(this.PropertyChanged, null))
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

 }

2 个答案:

答案 0 :(得分:2)

更新处理程序中的属性似乎会导致未定义的行为。

以异步方式延迟布局加载(和标记更新):

private static void LoadTriggerPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
    if ((bool)e.NewValue)
    {
        //run "async" on the same UI thread:
        Dispatcher.BeginInvoke(((UC)source).LoadLayout);
    }
}

答案 1 :(得分:0)

你应该看看DependencyObject.CoerceValue这通常是如何改变propertychanged回调中的依赖属性http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.coercevalue.aspx