【问题标题】:Tracking property changes with PostSharp使用 PostSharp 跟踪属性更改
【发布时间】:2018-09-17 02:10:13
【问题描述】:

我想在所有前面的页面都有效时启用给定的向导页面。这是我的视图模型:

[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));
    }
}

我期待 PostSharp 在 Wizard.Pages 更改时通知 Enabled 属性更改。不幸的是,它不起作用 - 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> 

【问题讨论】:

  • NotifyPropertyChangedAggregatable 方面之间的兼容性错误已在 PostSharp 版本 6.0.29 中修复。请将您的 NuGet 包更新到最新版本。

标签: c# wpf xaml postsharp .net-4.7.2


【解决方案1】:

我们已经调查了提供的样本,看起来原因是NotifyPropertyChangedAggregatable 方面之间的兼容性问题。

如果您删除或注释掉 [Aggregatable] 属性,则会按预期为 Enabled 属性引发事件。实际上,将Wizard 属性标记为引用而不是父级来修复NPC 行为就足够了。一旦Wizard 属性未被标记为父属性,您需要通过手动设置属性来确保正确的值。

请注意,您还需要在OnPropertyChanged 方法中添加属性名称检查以避免无限循环“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 ) );
    }
}

我们将继续调查该问题,并在修复发布后更新答案。

更新。 NotifyPropertyChangedAggregatable 方面之间的兼容性错误已在 PostSharp 版本 6.0.29 中得到修复。请将您的 NuGet 包更新到最新版本。

【讨论】:

    猜你喜欢
    • 2016-05-22
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 2012-03-07
    相关资源
    最近更新 更多