问题描述
我想在所有前面的页面都有效时启用给定的向导页面.这是我的视图模型:
I would like to enable a given wizard page when all preceding pages are valid. Here is my view model:
[Aggregatable]
[NotifyPropertyChanged]
[ContentProperty("Pages")]
public class Wizard
{
[Child, AggregateAllChanges]
public AdvisableCollection<Page> Pages { get; } = new AdvisableCollection<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));
}
}
我希望 PostSharp 在 Wizard.Pages
更改时通知 Enabled
属性更改.不幸的是它不起作用 - Enabled
属性没有更新.这段代码有什么问题?
I was expecting PostSharp to notify about Enabled
property change when Wizard.Pages
changes. It does not work unfortunately – there is no updates to Enabled
properties. What is wrong about this code?
要测试的 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>
推荐答案
我们已经调查了提供的样本,看起来原因是 NotifyPropertyChanged
和 Aggregatable
之间的兼容性问题代码>方面.
We have investigated the provided sample and it looks like the cause is a compatibility issue between the NotifyPropertyChanged
and Aggregatable
aspects.
如果您删除或注释掉 [Aggregatable]
属性,则会按预期为 Enabled
属性引发事件.实际上,甚至将 Wizard
属性标记为引用而不是父属性来修复 NPC 行为就足够了.一旦 Wizard
属性没有被标记为父属性,您需要通过手动设置属性来确保正确的值.
If you remove or comment out the [Aggregatable]
attributes, then the event is raised for the Enabled
property as expected. Actually, it's even enough to mark the Wizard
property as a reference instead of parent to fix the NPC behavior. Once the Wizard
property is not marked as a parent, you'll need to ensure the correct value by setting the property manually.
请注意,您还需要在OnPropertyChanged
方法中添加属性名称检查,以避免无限循环Wizard.Pages changed"->Enabled changed"->Wizard.Pages改变了"...
Please note, that you also need to add a property name check in the OnPropertyChanged
method to avoid the infinite loop "Wizard.Pages changed" -> "Enabled changed" -> "Wizard.Pages changed"...
[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 ) );
}
}
我们将继续调查该问题,并在修复发布后更新答案.
We'll continue investigating the issue and we'll update the answer once the fix is released.
更新. NotifyPropertyChanged
和 Aggregatable
方面之间的兼容性错误已在 PostSharp 6.0.29 版中修复.请将您的 NuGet 包更新到最新版本.
UPDATE. The compatibility bug between the NotifyPropertyChanged
and Aggregatable
aspects has been fixed in PostSharp version 6.0.29. Please update your NuGet packages to the latest version.
这篇关于使用 PostSharp 跟踪属性更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!