嵌套集合属性更改时更改集合属性

时间:2020-02-20 07:56:23

标签: c# wpf binding

完整解决方案:https://github.com/fallingsappy/portfolio/tree/master/DDrop

我有三个收藏。第一个:

public class Series : INotifyPropertyChanged
{
    private ObservableCollection<DropPhoto> _dropPhotosSeries;
    public ObservableCollection<DropPhoto> DropPhotosSeries
    {
        get
        {
            return _dropPhotosSeries;
        }
        set
        {
            _dropPhotosSeries = value;
            OnPropertyChanged(new PropertyChangedEventArgs("DropPhotosSeries"));
        }
    }
    private bool _canDrawPlot;
    public bool CanDrawPlot
    {
        get
        {
            return _dropPhotosSeries?.Where(x => x.Drop.RadiusInMeters != null).ToList().Count > 1 && _dropPhotosSeries?.Where(x => x.Drop.RadiusInMeters == null).ToList().Count == 0;
        }
        set
        {
            _canDrawPlot = value;
            OnPropertyChanged(new PropertyChangedEventArgs("CanDrawPlot"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChanged?.Invoke(this, e);
    }
}

第二:

public class DropPhoto : INotifyPropertyChanged
{
    private Drop _drop;
    public Drop Drop
    {
        get
        {
            return _drop;
        }
        set
        {
            _drop = value;
            OnPropertyChanged(new PropertyChangedEventArgs("Drop"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChanged?.Invoke(this, e);
    }
}

最后一个:

public class Drop : INotifyPropertyChanged
{
    private double? _radiusInMeters;
    public double? RadiusInMeters
    {
        get
        {
            return _radiusInMeters;
        }
        set
        {
            _radiusInMeters = value;
            OnPropertyChanged(new PropertyChangedEventArgs("RadiusInMeters"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChanged?.Invoke(this, e);
    }
}

我想每次其他两个集合(Drop和DropPhot.cs)发生变化时都更新(调用?)属性CanDrawPlot。例如,如果DropPhotosSeries.Count降低然后2,我需要将CanDrawPlot更改为false。 CanDrawPlot应该更新UI。这是XAML:

                <TabItem IsEnabled="{Binding CurrentSeries.CanDrawPlot, ElementName=AppMainWindow,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" x:Name="SingleSeriesPlotTabItem" Header="График" >
                    <uc:ScatterPlot x:Name="SingleSeriesPlot" User="{Binding User, ElementName=AppMainWindow}" ParticularSeriesIndex="{Binding ParticularSeriesIndex, ElementName=AppMainWindow}"/>
                </TabItem>

CurrentSeries在MainWindowXaml.cs中实例化:

public static readonly DependencyProperty CurrentSeriesProperty = DependencyProperty.Register("CurrentSeries", typeof(Series), typeof(MainWindow));
public Series CurrentSeries
{
    get { return (Series)GetValue(CurrentSeriesProperty); }
    set
    {
        SetValue(CurrentSeriesProperty, value);
    }
}

--------------- UPDATE -----------------

我根据Rob的回答相应地更改了代码:

public class Series : INotifyPropertyChanged
{
    public Series()
    {
        _dropPhotosSeries = new ObservableCollection<DropPhoto>();
        _dropPhotosSeries.CollectionChanged += _dropPhotosSeries_CollectionChanged;
    }
     private void _dropPhotosSeries_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        OnPropertyChanged(new PropertyChangedEventArgs(nameof(CanDrawPlot)));
    }

    private bool _canDrawPlot;
    public bool CanDrawPlot
    {
        get
        {
            return _dropPhotosSeries?.Where(x => x.Drop.RadiusInMeters != null).ToList().Count > 1 && _dropPhotosSeries?.Where(x => x.Drop.RadiusInMeters == null).ToList().Count == 0;
        }
        set
        {
            _canDrawPlot = value;
            OnPropertyChanged(new PropertyChangedEventArgs("CanDrawPlot"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChanged?.Invoke(this, e);
    }
}

现在,CanDrawPlot可以正确通知DropPhoto Collection中的更改。但是我还需要通过更改DropPhotoSeries的内部Drop类来调用它。这是我做的:

public class Drop : INotifyPropertyChanged
{
    Series _series;
    public Drop(Series series)
    {
        _series = series;
    }

    private double? _radiusInMeters;
    public double? RadiusInMeters
    {
        get
        {
            return _radiusInMeters;
        }
        set
        {
            _radiusInMeters = value;
            OnPropertyChanged(new PropertyChangedEventArgs(nameof(_series)));
            OnPropertyChanged(new PropertyChangedEventArgs("RadiusInMeters"));
        }
    }
}

它不起作用,怎么了?

1 个答案:

答案 0 :(得分:1)

您需要挂接到ObservableCollection的CollectionChanged事件,然后在其中必须为CanDrawPlot引发PropertyChanged。

示例:

将构造函数添加到Series类中,并在构造函数中实例化可观察的集合并订阅CollectionChanged事件。

public Series()
{
    _dropPhotosSeries = new ObservableCollection<DropPhoto>();
    _dropPhotosSeries.CollectionChanged += _dropPhotosSeries_CollectionChanged;
}

private void _dropPhotosSeries_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    OnPropertyChanged(new PropertyChangedEventArgs(nameof(CanDrawPlot)));
}