0

我有一个 WPF 应用程序,在这个应用程序中,我创建了一个自定义 UserControl。此控件能够从 XML 加载定义的布局。我想在 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));
        }
    }

 }
4

2 回答 2

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);
    }
}
于 2014-03-24T04:52:15.330 回答
0

您应该查看在DependencyObject.CoerceValuepropertychanged 回调中通常如何更改依赖属性http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.coercevalue.aspx

于 2014-03-24T13:04:50.190 回答