【问题标题】:C#, WPF - Items of ListView wont show when using ControlTemplate and BindingC#,WPF - 使用 ControlTemplate 和 Binding 时不会显示 ListView 的项目
【发布时间】:2020-12-22 07:49:42
【问题描述】:

我正在尝试将自己构建的类的对象添加到 ListView 中,其中包含 GridView。 DataBinding 工作没有任何问题,并且项目以正确的方式显示得很好。 这是 ListView 的 StyleTemplate:

<Style x:Key="Orig_FileViewTemplate" TargetType="ListView">            
        <Setter Property="VerticalAlignment" Value="Stretch"></Setter>
        <Setter Property="HorizontalAlignment" Value="Stretch"></Setter>            
    </Style>
<Style x:Key="FileViewTemplate" BasedOn="{StaticResource Orig_FileViewTemplate}" TargetType="ListView">
                    <Setter Property="ItemContainerStyle" Value="{StaticResource FileViewItemContainerTemplate}"></Setter>
                    <EventSetter Event="SelectionChanged" Handler="SelectionChangedOnListView" />                        
                </Style>

这是我的 ListView 对象之一,它使用这种样式:

<ListView Style="{DynamicResource FileViewTemplate}" Name="lv_FileSourceLV" Grid.Column="1" Grid.Row="0">
                                    <ListView.View>
                                        <GridView >
                                            <GridViewColumn Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,1'}">
                                                <GridViewColumn.CellTemplate>
                                                    <DataTemplate>
                                                        <Image MaxWidth="30" Margin="3,2,3,2" VerticalAlignment="Center" HorizontalAlignment="Center">
                                                            <Image.Style>
                                                                <Style TargetType="{x:Type Image}">
                                                                    <Style.Triggers>
                                                                        <DataTrigger Binding="{Binding IsFolder}" Value="True">
                                                                            <Setter Property="Source" Value="{StaticResource Folder_Icon }" />
                                                                        </DataTrigger>
                                                                        <DataTrigger Binding="{Binding IsFolder}" Value="False">
                                                                            <Setter Property="Source" Value="{StaticResource File_Icon }" />
                                                                        </DataTrigger>
                                                                    </Style.Triggers>
                                                                </Style>
                                                            </Image.Style>
                                                        </Image>
                                                    </DataTemplate>
                                                </GridViewColumn.CellTemplate>
                                            </GridViewColumn>
                                            <GridViewColumn HeaderContainerStyle="{DynamicResource FileViewNameColumn}" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,45'}" DisplayMemberBinding="{Binding Name }" />
                                            <GridViewColumn HeaderContainerStyle="{DynamicResource FileViewSizeColumn}" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,175'}" DisplayMemberBinding="{Binding Size}" />
                                            <GridViewColumn HeaderContainerStyle="{DynamicResource FileViewDateColumn}" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,275'}" DisplayMemberBinding="{Binding Date}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>

它应该正常工作,但现在我的问题.... 我的 GUI 上有大量此类 ListView,我尝试将整个样式放入 ResourceManager 以使我的代码更加简洁并节省大量冗余代码。 但是当我使用这样的样式时:

<Style x:Key="FileViewTemplate" BasedOn="{StaticResource Orig_FileViewTemplate}" TargetType="ListView">
                    <Setter Property="ItemContainerStyle" Value="{StaticResource FileViewItemContainerTemplate}"></Setter>
                    <EventSetter Event="SelectionChanged" Handler="SelectionChangedOnListView" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate  TargetType="{x:Type ListView}">
                                <ListView>
                                    <ListView.View>
                                        <GridView>
                                            <GridViewColumn Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,1'}">
                                                <GridViewColumn.CellTemplate>
                                                    <DataTemplate>
                                                        <Image MaxWidth="30" Margin="3,2,3,2" VerticalAlignment="Center" HorizontalAlignment="Center">
                                                            <Image.Style>
                                                                <Style TargetType="{x:Type Image}">
                                                                    <Style.Triggers>
                                                                        <DataTrigger Binding="{Binding IsFolder}" Value="True">
                                                                            <Setter Property="Source" Value="{StaticResource Folder_Icon }" />
                                                                        </DataTrigger>
                                                                        <DataTrigger Binding="{Binding IsFolder}" Value="False">
                                                                            <Setter Property="Source" Value="{StaticResource File_Icon }" />
                                                                        </DataTrigger>
                                                                    </Style.Triggers>
                                                                </Style>
                                                            </Image.Style>
                                                        </Image>
                                                    </DataTemplate>
                                                </GridViewColumn.CellTemplate>
                                            </GridViewColumn>
                                            <GridViewColumn HeaderContainerStyle="{DynamicResource FileViewNameColumn}" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,45'}" DisplayMemberBinding="{Binding Name}" />
                                            <GridViewColumn HeaderContainerStyle="{DynamicResource FileViewSizeColumn}" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,175'}" DisplayMemberBinding="{Binding Size}" />
                                            <GridViewColumn HeaderContainerStyle="{DynamicResource FileViewDateColumn}" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,275'}" DisplayMemberBinding="{Binding Date}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>

并以这种方式使用 ListView:

<ListView Style="{DynamicResource FileViewTemplate}" Name="lv_FileSourceLV" Grid.Column="1" Grid.Row="0"></ListView>

即使我向其中添加了项目,GUI 上的 ListView 也将是空的。 我以相同的方式添加它们:

lv_FileSourceLV.Items.Add(file)

当我在模板中使用 DataBinding 时,我认为应该以不同的方式处理它,但我不知道如何。

你能告诉我我做错了什么吗? 提前谢谢!

编辑:使用类似 GridView 的资源

<GridView x:Key="FileViewGrid">

我现在收到此错误:

System.Windows.Markup.XamlParseException HResult=0x80131501
Message='Set property 'System.Windows.FrameworkElement.Style' 抛出一个 例外。'行号“331”和行位置“106”。内部异常 1:InvalidOperationException:视图不能被多人共享 列表视图。

这是我当前的代码:

<DataTemplate x:Key="FileViewNameTemplate">
        <TextBlock Text="{Binding Name}"/>
    </DataTemplate>
    <DataTemplate x:Key="FileViewSizeTemplate">
        <TextBlock Text="{Binding Size}"/>
    </DataTemplate>
    <DataTemplate x:Key="FileViewDateTemplate">
        <TextBlock Text="{Binding Date}"/>
    </DataTemplate>
    <DataTemplate x:Key="FileViewImageTemplate">
        <Image MaxWidth="30" Margin="3,2,3,2" VerticalAlignment="Center" HorizontalAlignment="Center">
            <Image.Style>
                <Style TargetType="{x:Type Image}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsFolder}" Value="True">
                            <Setter Property="Source" Value="{StaticResource Folder_Icon }" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding IsFolder}" Value="False">
                            <Setter Property="Source" Value="{StaticResource File_Icon }" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Image.Style>
        </Image>
    </DataTemplate>
    <GridView x:Key="FileViewGrid" x:Shared="False">
            <GridViewColumn CellTemplate="{StaticResource FileViewImageTemplate}" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,1'}" />
            <GridViewColumn CellTemplate="{StaticResource FileViewNameTemplate}" HeaderContainerStyle="{DynamicResource FileViewNameColumn}" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,45'}"/>
            <GridViewColumn CellTemplate="{StaticResource FileViewSizeTemplate}" HeaderContainerStyle="{DynamicResource FileViewSizeColumn}" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,175'}"/>
            <GridViewColumn CellTemplate="{StaticResource FileViewDateTemplate}" HeaderContainerStyle="{DynamicResource FileViewDateColumn}" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}, Converter={StaticResource percentageConverter}, ConverterParameter='0,275'}"/>
    </GridView>
    <Style x:Key="FileViewTemplate" BasedOn="{StaticResource Orig_FileViewTemplate}" TargetType="ListView">
        <Setter Property="ItemContainerStyle" Value="{StaticResource FileViewItemContainerTemplate}"></Setter>
        <EventSetter Event="SelectionChanged" Handler="SelectionChangedOnListView" />
        <Setter Property="View" Value="{DynamicResource FileViewGrid}"/>
    </Style>
    

我也试过把“x:Shared=False”属性放到GridView和Style中,把GridView直接放到“FileViewDateTemplate的View-Property中。什么都没有成功。

【问题讨论】:

  • 您注意到我对已编辑答案的评论了吗?
  • 是的,我注意到了,并将编辑我的帖子更改为我的代码的当前版本。不幸的是,仍然抛出异常。
  • 我无法重现该错误。共享的 GridView 资源对我来说很好用。您确定您在应用程序中看到异常,而不仅仅是在 Visual Studio 的 XAML 设计器中?
  • 是的,我在启动时收到此错误。它停在“InitializeComponent();”
  • 不知道。请注意,当然没有必要将DisplayMemberBinding="{Binding Name}" 替换为 CellTemplate。我只是在回答中使用了一个简单的 DataTemplate 作为示例。

标签: c# wpf listview templates binding


【解决方案1】:

ListView 的 ControlTemplate 中有 ListView 是错误的。您根本不应该设置 Template 属性。

改为为 View 属性添加一个 setter,它使用共享的 GridView 资源 - 并且还可以选择将 DataTemplate 设为资源。

您通常也不会以编程方式将元素添加到 ItemsControl 的 Items 集合。在主视图模型中应该有一个 ObservableCollection 属性,ItemsSource 属性将绑定到该属性。

<Window.Resources>
    <DataTemplate x:Key="MyCellTemplate">
        <TextBlock Text="{Binding Name}"/>
    </DataTemplate>
    <GridView x:Key="MyGridView" x:Shared="False">
        <GridViewColumn Header="Name"
                        CellTemplate="{StaticResource MyCellTemplate}"/>
    </GridView>
    <Style x:Key="MyListViewStyle" TargetType="ListView">
        <Setter Property="View" Value="{StaticResource MyGridView}"/>
    </Style>
</Window.Resources>
<Grid>
    <ListView Style="{StaticResource MyListViewStyle}"
              ItemsSource="{Binding MyItems}"/>
</Grid>

编辑:共享样式资源也应该可以工作:

<Style x:Key="MyListViewStyle" x:Shared="False" TargetType="ListView">
    <Setter Property="View">
        <Setter.Value>
            <GridView>
                <GridViewColumn Header="Name"
                    CellTemplate="{StaticResource MyCellTemplate}"/>
            </GridView>
        </Setter.Value>
    </Setter>
</Style>

【讨论】:

  • 感谢您的回答!不幸的是,我现在收到此错误: System.Windows.Markup.XamlParseException HResult=0x80131501 Message='Set property 'System.Windows.FrameworkElement.Style' throw an exception。行号“331”和行位置“106”。内部异常1:InvalidOperationException:视图不能被多个ListView共享。
  • 抱歉,没有用多个 ListView 进行测试。有关解决方案,请参阅使用共享 GridView 资源编辑的答案。如果 XAML 设计器仍在抱怨,请忽略它并可能重新启动 Visual Studio。
猜你喜欢
  • 1970-01-01
  • 2011-01-05
  • 2010-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多