2016-01-29 5 views
1

У меня есть ItemsControl с его ItemsSource, связанным с ObservableCollection<T>, используя мой собственный UserControl как ItemTemplate:Как определить, когда шаблонный UserControl удаляется из пользовательского интерфейса (не просто скрыты в UI)

<ItemsControl ItemsSource="{Binding Path=MyObservableColletion, Mode=OneWay}"> 

    <ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <MyControls:MyUserControl /> 
    </DataTemplate> 
    </ItemsControl.ItemTemplate> 

</ItemsControl> 

Я он подключен таким образом, что пользовательский интерфейс обновляется по мере добавления/удаления элементов в/из коллекции.

Когда элемент удаляется из коллекции, я хочу обнаружить это в коде для типичного шаблона MyUserControl. Как я могу это сделать?

Я заметил, что Unloaded событие срабатывает в этом случае, но это не подходит для моей цели, потому что Unloaded также срабатывает, когда пользовательский интерфейс, содержащий мой ItemsControl просто скрыт/разрушилась (например, когда он в TabControl и вкладка выключен).

Есть ли другое событие для этой цели или способ обнаружения в теле обработчика Unloaded того, что мой элемент управления определенно удален, а не просто скрыт?

+0

Где находится ваш 'MyObservableCollection', это связано с использованием viewmodel? и 'Mode = OnWay' должен быть' Mode = OneWay' –

+0

Это приложение не использует MVVM, поэтому нет viewmodel - MyObservableCollection находится в коде для элемента управления, который содержит ItemControl. Мой предыдущий пример кода XAML немного упрощен - на самом деле я использую RelativeSource для привязки привязки. (Также я исправил опечатку - спасибо.) – Ross

+0

Вы можете использовать события на ObservableCollection, которые я думаю. https://msdn.microsoft.com/en-us/library/ms668604%28v=vs.110%29.aspx 'CollectionChanged и PropertyChanged' события –

ответ

0

Поскольку ваш «MyObservableColletion» должен быть типа ObservableCollection, вы должны подписаться на это событие «CollectionChanged». Его EventHandler будет запускаться при добавлении и удалении. В случае args вы найдете массив oldItems, который будет содержать коллекцию, которая была удалена из коллекции.

public void CollectionChangedEventHandler(object sender, NotifyCollectionChangedEventArgs args) 
{ 
    var deletedItem = args.OldItems.FirstOrDefault(); 
} 

В WPF вы не имеете дело с элементами управления в коде. никогда. Вы играете с данными, которые представлены элементами управления.

+0

Jordy van Eijk предложил это в комментарии к исходному вопросу, но этого будет недостаточно. Мне нужно обнаружить удаленный пользовательский элемент управления, чтобы я мог отключить события пользовательского интерфейса и т. Д. Выполнение этого в событии CollectionChanged в OC было бы нерелевантным/невозможным, поскольку это событие касается только данных. – Ross

+0

«В WPF вы не имеете дело с элементами управления в коде. Никогда никогда». Иногда вы это делаете, как и в моем случае при отсоединении пользовательского интерфейса. – Ross

+0

WHAAAAAAAAT? вам не нужно это делать. Поскольку элемент управления установлен, списки вызовов обработчиков событий также будут. Я бы сказал, что ваш код очистки имеет неправильную концепцию. После того, как я научился правильно работать с WPF, мне почти никогда не приходилось работать с элементами управления в коде. – user853710

0

Нам нужно проверить, нет ли каких-либо изменений для снятого соединения UserControl. Одним из таких свойств является DataContext, так как после UserControl нет в ItemsControl, так что это DataContext будет сброшено. И для отключенных элементов управления установлено значение {DisconnectedItem}.

Добавить этот код в ваш UserControl.

protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) 
{ 
    if (e.Property.Name == "DataContext" && e.NewValue.ToString() == "{DisconnectedItem}") 
    { 
     System.Diagnostics.Debug.WriteLine(this + " : I am removed !"); 
    } 
    base.OnPropertyChanged(e); 
}