Как я могу получать уведомления при смене типа коллекции DP? - PullRequest
1 голос
/ 13 октября 2019

У меня плохое знание английского, потому что я не являюсь носителем английского языка.

Я создал поведение, следующее за работой с элементом управления TextBox. У поведения есть DP типа коллекции с именем Items.

class HighlightBehavior : Behavior<TextBox>
{

public List<TextStyle>Items
{
    get { return (List<TextStyle>)GetValue(ItemsProperty); }
    set { SetValue(ItemsProperty, value); }
}

public static readonly DependencyProperty ItemsProperty =
    DependencyProperty.Register("Items", typeof(List<TextStyle>), typeof(HighlightBehavior), new PropertyMetadata(ItemsChanged));

private static void ItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
   // break point 
}

}

И ... Я создал MainWindow для использования в качестве приведенного выше кода поведения.

<MainWindow>
  <TextBox>
    <i:interaction.Behaviors>
      <behavior:HighlightBehavior/>
    </i:interaction.Behavior>
  </TextBox>
</MainWindow>

И я написалMainWindowViewModel, который имеет DP типа коллекции с именем HighlightItems.

class MainWindowViewModel : ViewModelBase
{
    public List<TextStyle> HighlightItems
    {
        get { return (List<TextStyle>)GetValue(HighlightItemsProperty ); }
        set { SetValue(HighlightItemsProperty , value); }
    }

    public static readonly DependencyProperty HighlightItemsProperty =
        DependencyProperty.Register("HighlightItems", typeof(List<TextStyle>), typeof(HighlightBehavior), new PropertyMetadata(null));

    public MainWindowViewModel()
    {
        SetValue(HighlightItemsProperty, new List<TextStyle>());
    }
}

И я связал MainWindowViewModel с MainWindow и соединил HighlightItems (DP) MainWindowViewModel с элементами (DP) HighlightBehavior в качестве следующего кода.

<MainWindow>
  <TextBox>
    <i:interaction.Behaviors>
      <behavior:HighlightBehavior Items="{Binding HighlightItems, Mode=TwoWay}"/>
    </i:interaction.Behavior>
  </TextBox>
</MainWindow>

Подводя итог, структура выглядит следующим образом.

enter image description here

Я ожидал, что ItemsChanged of HighlightBehavior вызывается всякий раз, когдаПредметы изменены. Но он не вызывается.

Я хочу получать уведомления всякий раз, когда DP-тип коллекции (Items) HighlightBehavior изменяется. Что я должен сделать, чтобы достичь этой цели?

Спасибо за чтение. Я подожду ответа.

Ответы [ 2 ]

2 голосов
/ 14 октября 2019

Я считаю, что вы ищете ObservableCollection . Это особый тип коллекции, который вызывает событие CollectionChanged всякий раз, когда элемент добавляется, удаляется, изменяется или перемещается.

Я рекомендую следующее:

  1. Вместообъявив HighlightItems как List<TextStyle>, объявить его как ObservableCollection<TextStyle>.

  2. Добавить еще один метод к HighlightBehavior для обработки CollectionChanged, например:
    HighlightItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)

  3. Ваша текущая реализация ItemsChanged будет вызываться всякий раз, когда установлена ​​HighlightItems. Используйте это, чтобы прикрепить обработчик событий к CollectionChanged следующим образом:

var col = (ObservableCollection<TextStyle>)e.NewValue;
if (col != null) { col.CollectionChanged += HighlightItemsCollectionChanged; }
Не забудьте удалить любой существующий обработчик событий из предыдущей коллекции, если HighlightItems настроен на перемещение, чем один раз. Вы можете добавить это к ItemsChanged вместе с предыдущим фрагментом:
col = (ObservableCollection<TextStyle>)e.OldValue;
if (col != null) { col.CollectionChanged -= HighlightItemsCollectionChanged; }
HighlightItemsCollectionChanged теперь будет вызываться всякий раз, когда элемент добавляется или удаляется из HighlightItems. Делайте все, что вам нужно сделать в этом методе, или если вы хотите, чтобы код также выполнялся при замене самой коллекции, вы можете создать другой метод, который фактически делает то, что вы хотите, и затем вызывать этот метод как из ItemsChanged, так и HighlightItemsCollectionChanged.
0 голосов
/ 14 октября 2019

Спасибо. Я изменил код, следуя вашему совету, и теперь я могу получать уведомления, когда элемент коллекции изменяется.

Я знал о ObservableCollection, но не знал, как правильно использовать событие EventChanged.

Фактически, ранее я пытался использовать ObservableCollection и регистрировал метод делегата CollectionChanged в Constructer следующим образом, но он не вызывается.

public ObservableCollection<TextStyle> Items
{
    get { return (ObservableCollection<TextStyle>)GetValue(ItemsProperty); }
    set { SetValue(ItemsProperty, value); }
}

// Using a DependencyProperty as the backing store for Items.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemsProperty =
    DependencyProperty.Register("Items", typeof(ObservableCollection<TextStyle>), typeof(HighlightBehavior),
          new PropertyMetaData(null));

public HighlightBehavior()
{
    SetValue(ItemsProperty, new ObservableCollection<TextStyle>());
    Items.CollectionChanged += OnCollectionChanged;
}

private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // The code when the collection is changed.
}

Теперь я зарегистрировал метод делегата CollectionChangedв методе PropertyChangedCallback, как показано ниже, и вызывается его (метод OnCollectionChanged в следующем коде).

public ObservableCollection<TextStyle> Items
{
    get { return (ObservableCollection<TextStyle>)GetValue(ItemsProperty); }
    set { SetValue(ItemsProperty, value); }
}

// Using a DependencyProperty as the backing store for Items.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemsProperty =
    DependencyProperty.Register("Items", typeof(ObservableCollection<TextStyle>), typeof(HighlightBehavior),
          new PropertyMetaData(ItemsChanged));

private static void ItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var col = (ObservableCollection<TextStyle>)e.NewValue;
    if (col != null) { col.CollectionChanged += OnCollectionChanged; ; }

    col = (ObservableCollection<TextStyle>)e.OldValue;
    if (col != null) { col.CollectionChanged -= OnCollectionChanged; }
}

public HighlightBehavior()
{
    SetValue(ItemsProperty, new ObservableCollection<TextStyle>());
}

Спасибо за подробный ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...