2015-08-18 5 views
2

У меня есть Пользовательское поведение, прикрепленное к моим ListViewItems, которое запускается на Загружено и DataContextChanged.Запустить поведение ListViewItem при изменении свойства?

Что такое поведение пересекают VisualTree и путем определения его прямых родителей, установите Видимость в Видимый или Collapsed.

При начальной загрузке, и всякий раз, когда я добавляю/удаляю ListViewItem в ListView, он работает правильно.

Однако некоторые взаимодействия изменяют только Свойство ViewModel, привязанное к элементу ListViewItem. То, что я хочу сделать, когда это свойство изменяется, я хочу, чтобы по-прежнему запускал настраиваемое поведение, которое устанавливает видимость только для этого списка ListViewItem. Поскольку DataContext и Loaded не запускаются, моего поведения не происходит.

Есть ли способ сделать это?

Это мой код для справки:

<DataTemplate x:Key="DataTemplate_Item"> 
     <Grid x:Name="Grid_TemplateRoot"> 
      <i:Interaction.Behaviors> 
       <Dovetail_UI_Register_Controls_Behaviors:SetItemVisibilityBehavior /> 
      </i:Interaction.Behaviors> 
      <TextBlock Text={Binding Path="ItemName"} 
     </Grid> 
</DataTemplate> 

И поведение:

public class OnLoadedOrDatacontextChangedBehavior<T> : OnLoadedBehavior<T> where T : FrameworkElement 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     TypedAssociatedObject.Loaded += ChangeVisibility(); 
     TypedAssociatedObject.AddDataContextChangedHandler(OnDataContextChanged); 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 

     TypedAssociatedObject.Loaded -= ChangeVisibility(); 
     TypedAssociatedObject.RemoveDataContextChangedHandler(OnDataContextChanged); 
    } 

    protected virtual void OnDataContextChanged(object sender, EventArgs args) 
    { 
     ChangeVisibility(); 
    } 

    private void ChangeVisibility() 
    { 
    //Change visibility here 
    } 
} 

Спасибо!

+0

Как вообще это должно быть? Может ли ваш связанный контекст данных реализовывать какой-либо интерфейс, так что в вашем 'OnDataContextChanged' вы можете использовать' IMyInterface context = ((FrameworkElement) отправитель) .DataContext как IMyInterface', а затем также присоединить обработчики для свойств, измененных событиями? –

+0

Это только для определенного ListView. Извините, я немного новичок в этом, что вы имеете в виду приложением обработчиков к измененным событиям свойства? Отличается ли он от INotifyPropertChanged из ViewModel? Спасибо – Water

+1

Если у вас есть контроль над тем, что связано, и ваши модели просмотров _are_ с помощью 'INotifyPropertyChanged', то вы можете обновить то, что у меня было как« INotifyPropertyChanged context = ((FrameworkElement) отправитель) .DataContext as INotifyPropertyChanged; context.PropertyChanged + = (s, e) => ChangeVisibility(); 'например. –

ответ

1

Если вы не публикуете это как библиотеку классов, которая должна поддерживать контекст данных, входящий как любой объект, то вы можете обновить обработчик, чтобы прослушать эти изменения свойств в контексте данных.

Например:

protected virtual void OnDataContextChanged(object sender, EventArgs args) 
{ 
    ChangeVisibility(); 

    // Listen for any further changes which effect visibility. 
    INotifyPropertyChanged context = ((FrameworkElement)sender).DataContext as INotifyPropertyChanged; 
    context.PropertyChanged += (s, e) => ChangeVisibility(); 
} 

Вы можете дополнительно расширить это далее, например, если ваши методы обработчика для контекста данных изменения использования DependencyPropertyChangedEventHandler, то вы могли бы очистки, что PropertyChanged обработчик. Кроме того, вы можете просматривать только определенные свойства в вашем обработчике PropertyChanged. Расширенный пример:

protected virtual void OnDataContextChanged(object sender, DependencyPropertyChangedEventHandler args) 
{ 
    ChangeVisibility(); 
    INotifyPropertyChanged context; 

    // Cleanup any handler attached to a previous data context object. 
    context = e.OldValue as INotifyPropertyChanged; 
    if (context != null) 
     context.PropertyChanged -= DataContext_PropertyChanged; 

    // Listen for any further changes which effect visibility. 
    context = e.NewValue as INotifyPropertyChanged; 
    if (context != null) 
     context.PropertyChanged += DataContext_PropertyChanged; 
} 

private void DataContext_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    if (e.PropertyName == "MyTargetProperty") 
    { 
     ChangeVisibility(); 
    } 
} 
+0

Еще раз спасибо! : D – Water