Изменить свойства коллекции при изменении свойств вложенной коллекции - PullRequest
0 голосов
/ 20 февраля 2020

Полное решение: 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);
    }
}

Я хочу обновлять (вызывать?) Свойство CanDrawPlot каждый раз, когда что-то происходит с две другие коллекции (Drop и DropPhot.cs). Например, если DropPhotosSeries.Count опускается ниже 2, мне нужно изменить CanDrawPlot на false. CanDrawPlot должен обновить пользовательский интерфейс. Вот 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);
    }
}

--------------- ОБНОВЛЕНИЕ --- ------------

Я изменил свой код в соответствии с ответом Роба:

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. Но мне нужно вызывать его также изменениями внутреннего класса Drop в DropPhotoSeries. Вот что я сделал:

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 Ответ

1 голос
/ 20 февраля 2020

Вам необходимо подключиться к событию CollectionChanged объекта ObservableCollection, и там вы должны вызвать PropertyChanged для CanDrawPlot.

ПРИМЕР:

Добавить конструктор в класс 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)));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...