我的ListViewItems附加自定义行为,触发已加载和DataContextChanged。
此行为的作用是遍历VisualTree并确定其直接父级,将可见性设置为可见或折叠< /强>
在初始加载时,每当我向ListView添加/删除ListViewItem时,它都能正常工作。
但是,某些交互只会更改绑定到ListViewItem的ViewModel的属性。我想要做的是,每当此属性更改时,我想仍然触发仅为该ListViewItem设置Visibility 的自定义行为。由于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 :(得分: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();
}
}