在 属性 更改时触发 ListViewItem 行为?
Trigger a ListViewItem Behavior on Property Change?
我有一个 自定义行为 附加到我的 ListViewItems,它在 Loaded 和 DataContextChanged 时触发。
此行为的作用是遍历 VisualTree 并通过确定其 直接父级 ,将 Visibility 设置为 Visible 或 已折叠。
在初始加载时,每当我向 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
}
}
谢谢!
如果您不将其发布为 class 需要支持作为任何对象传入的数据上下文的库,那么您可以更新您的处理程序以监听那些 属性 更改您的数据上下文。
例如:
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();
}
}
我有一个 自定义行为 附加到我的 ListViewItems,它在 Loaded 和 DataContextChanged 时触发。
此行为的作用是遍历 VisualTree 并通过确定其 直接父级 ,将 Visibility 设置为 Visible 或 已折叠。
在初始加载时,每当我向 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
}
}
谢谢!
如果您不将其发布为 class 需要支持作为任何对象传入的数据上下文的库,那么您可以更新您的处理程序以监听那些 属性 更改您的数据上下文。
例如:
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();
}
}