我有一个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));
}
}
}
答案 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