我想在前面的所有页面均有效时启用给定的向导页面。这是我的视图模型:
[Aggregatable]
[NotifyPropertyChanged]
[ContentProperty("Pages")]
public class Wizard
{
[Child, AggregateAllChanges]
public AdvisableCollection<Page> Pages { get; } = new AdvisableCollection<Page>();
}
这里是Page
本身:
[Aggregatable]
[NotifyPropertyChanged]
public class Page : INotifyPropertyChanged
{
[Parent] Wizard Wizard { get; set; }
public string Name { get; set; }
public bool Valid { get; set; }
[SafeForDependencyAnalysis]
public bool Enabled
{
get
{
if(Depends.Guard)
Depends.On(Wizard.Pages);
return Wizard.Pages
.TakeWhile(p => p != this)
.All(p => p.Valid);
}
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
if (Wizard != null)
NotifyPropertyChangedServices.SignalPropertyChanged(Wizard, nameof(Wizard.Pages));
}
}
我期望Enabled
更改时,PostSharp会通知Wizard.Pages
属性更改。不幸的是,它无法正常工作-Enabled
属性没有更新。此代码有什么问题?
要测试的XAML:
<Window.DataContext>
<local:Wizard>
<local:Page Name="First"/>
<local:Page Name="Second"/>
<local:Page Name="Third"/>
<local:Page Name="Forth"/>
</local:Wizard>
</Window.DataContext>
<ListBox ItemsSource="{Binding Pages}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:Page}">
<CheckBox Content="{Binding Name}" IsChecked="{Binding Valid}" IsEnabled="{Binding Enabled}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
答案 0 :(得分:0)
我们已经对提供的示例进行了调查,原因似乎是NotifyPropertyChanged
和Aggregatable
两个方面之间的兼容性问题。
如果您删除或注释掉[Aggregatable]
属性,则会为Enabled
属性引发事件,如预期的那样。实际上,将Wizard
属性标记为引用而不是将其标记为父项足以解决NPC行为。一旦Wizard
属性未标记为父级,您将需要通过手动设置该属性来确保值正确。
请注意,还需要在OnPropertyChanged
方法中添加属性名称检查,以避免无限循环“ Wizard.Pages更改”->“ Enabled更改”->“ Wizard.Pages更改”。 ..
[Aggregatable]
[NotifyPropertyChanged]
public class Page : INotifyPropertyChanged
{
//[Parent]
[Reference]
public Wizard Wizard { get; set; }
public string Name { get; set; }
public bool Valid { get; set; }
[SafeForDependencyAnalysis]
public bool Enabled
{
get
{
if ( Depends.Guard )
Depends.On( Wizard.Pages );
return Wizard.Pages
.TakeWhile( p => p != this )
.All( p => p.Valid );
}
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
void OnPropertyChanged( string propertyName )
{
PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
if ( Wizard != null && propertyName != nameof( Enabled ) )
NotifyPropertyChangedServices.SignalPropertyChanged( Wizard, nameof( Wizard.Pages ) );
}
}
我们将继续调查该问题,并在修复程序发布后更新答案。
更新。 PostSharp版本6.0.29已修复NotifyPropertyChanged
和Aggregatable
之间的兼容性错误。请更新您的NuGet软件包到最新版本。