我如何正确实现样式触发器以在 ListView 完成填充时触发?

How do i correctly implement a style trigger to fire when a ListView finishes populating?

我想设置 ListView 的样式,以便在填充后外观会发生变化。我发现 ListView 中有一个叫做 ItemContainerGenerator 的东西,它包含一个 Status 属性,完成后将被设置为 ContainersGenerated(我想想 ).

所以为了实现这个目标,我认为最好的方法是定义一个样式数据触发器来触发 属性。

但它不起作用(当然)。我看到的是输出中的以下错误 -

System.Windows.Data Error: 17 : Cannot get 'Status' value (type 'GeneratorStatus') from '' (type 'ListView'). BindingExpression:Path=(ItemContainerGenerator.Status); DataItem='ListView' (Name=''); target element is 'ListView' (Name=''); target property is 'NoTarget' (type 'Object') TargetException:'System.Reflection.TargetException: Object does not match target type. at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target) at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index) at MS.Internal.Data.PropertyPathWorker.GetValue(Object item, Int32 level) at MS.Internal.Data.PropertyPathWorker.RawValue(Int32 k)'

在提问时符合 Minimal, Complete and Verifiable Example 要求 -

  1. 在 Visual Studio 中创建一个名为 'MCVE' 的新项目。
  2. 将以下代码复制并粘贴到 MainWindow.xaml 代码上。
  3. 运行 程序。获取数据错误。默默流泪

    <Window x:Class="MCVE.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:MCVE" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <ListView> <ListView.Style> <Style TargetType="{x:Type ListView}"> <Style.Triggers> <DataTrigger Binding="{Binding (ItemContainerGenerator.Status), RelativeSource={RelativeSource Self}}" Value="{x:Static GeneratorStatus.ContainersGenerated}"> <!-- This is where I'd put my setters - IF THE TRIGGER WORKED!!! --> <Setter Property="Background" Value="Red" /> </DataTrigger> </Style.Triggers> </Style> </ListView.Style> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Setter Property="BorderThickness" Value="0" /> <Setter Property="Margin" Value="0" /> <Setter Property="Padding" Value="0" /> </Style> </ListView.ItemContainerStyle> <ListView.ItemsPanel> <ItemsPanelTemplate> <UniformGrid HorizontalAlignment="Center" Rows="1" /> </ItemsPanelTemplate> </ListView.ItemsPanel> <ListViewItem>Foo</ListViewItem> <ListViewItem>Bar</ListViewItem> <ListViewItem>Baz</ListViewItem> </ListView> </Window>

(不幸的是,因为它都在 XAML 中,我必须将整个代码块包装在 ` 中才能显示)

那么我怎样才能正确创建一个数据触发器,它会在 ListView 完成填充时触发?

删除 ItemContainerGenerator.Status 两边的括号。为我工作。顺便说一句,如果您正在使用回收,您将在滚动时不断切换状态。如果您的列表需要很长时间才能填充,听起来您应该使用回收和虚拟化。对于 "normal" 个项目,用户甚至不会看到未完成的状态,因为它会立即发生。