【问题标题】:ListView: define ItemsPanelTemplate in resource dictionaryListView:在资源字典中定义 ItemsPanelTemplate
【发布时间】:2011-08-08 00:28:24
【问题描述】:

我有一个 ListView,它的布局看起来像一个 Windows 资源管理器视图(图标 + 一些细节),绑定到 ViewModel 中某处的列表。

我的目标是能够随时在资源管理器视图或经典视图之间切换。

我可以直接在ListView.ItemsPanel 字段中定义一个ItemsPanelTemplate 来完成正确显示布局的工作。现在,我想在资源中定义它,这样我就可以在不同的视图中使用它,尤其是在一个控件中,用户应该可以在资源管理器视图或经典列表视图之间进行选择(默认呈现一个列表)

你是怎么做到的?我不能在我的ResourceDictionary 中定义任何ItemsPanelTemplate,如果我定义了DataTemplate,它是不兼容的(虽然我认为遵循纯逻辑,ItemsPanelTemplate 应该继承自DataTemplate,但它实际上并没有看起来像这样)。

实际列表的代码 sn-p:

<ListView.ItemsPanel>
    <ItemsPanelTemplate>
        <WrapPanel
            Width="{Binding (FrameworkElement.ActualWidth),
                RelativeSource={RelativeSource 
                AncestorType=ScrollContentPresenter}}"
            ItemWidth="{Binding (ListView.View).ItemWidth,
                RelativeSource={RelativeSource AncestorType=ListView}}"
            ItemHeight="{Binding (ListView.View).ItemHeight,
                RelativeSource={RelativeSource AncestorType=ListView}}" 
            />
            <!--
            MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
            -->
    </ItemsPanelTemplate>
</ListView.ItemsPanel>

<ListView.ItemTemplate>
    <DataTemplate>
        <StackPanel
            Orientation="Horizontal" 
            Height="Auto" 
            Width="150" >
            <Image 
                Source="{Binding Path=Appli.AppType, Converter={StaticResource TypeToIconConverter}}"
                Margin="5"
                Height="50"
                Width="50" />
            <StackPanel 
                VerticalAlignment="Center"
                Width="90" >
                <TextBlock 
                    Text="{Binding Path=Appli.AppName}" 
                    FontSize="13" 
                    HorizontalAlignment="Left" 
                    TextWrapping="WrapWithOverflow"
                    Margin="0,0,0,1" />
                <TextBlock 
                    Text="{Binding Path=Appli.AppType}" 
                    FontSize="9" 
                    HorizontalAlignment="Left" 
                    Margin="0,0,0,1" />
            </StackPanel>
        </StackPanel>
    </DataTemplate>
</ListView.ItemTemplate>

ItemTemplate 保存在静态资源中很容易做到,但现在我对ItemsPanelTemplate 无能为力...

有什么想法吗?我正在使用 MVVM,所以我尽量不使用代码隐藏

【问题讨论】:

    标签: wpf listview mvvm datatemplate itemspanel


    【解决方案1】:

    您可以为此使用整个 ListView 的样式。所以你会这样做:

    <Grid.Resources>
        <Style x:Key="ListViewStyle" TargetType="ListView">
            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <WrapPanel 
                            Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
                            ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}"
                            ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}" />
                            <!-- 
                            MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}" 
                            -->
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Grid.Resources>
    
    <ListView
        SelectionMode="Single"
        VerticalAlignment="Stretch"
        HorizontalAlignment="Stretch"
        HorizontalContentAlignment="Center"
        VerticalContentAlignment="Bottom"
        ScrollViewer.VerticalScrollBarVisibility="Auto"
        ItemsSource="{Binding ListUserApps, UpdateSourceTrigger=PropertyChanged}"
        SelectedIndex="{Binding SelectedUserApp, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        Background="White"
        Style="{StaticResource ListViewStyle}">
    
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel
                    Orientation="Horizontal"
                    Height="Auto"
                    Width="150">
                    <Image
                        Source="{Binding Path=Appli.AppType, Converter={StaticResource TypeToIconConverter}}"
                        Margin="5"
                        Height="50"
                        Width="50"/>
                    <StackPanel
                        VerticalAlignment="Center"
                        Width="90">
    
                        <TextBlock
                            Text="{Binding Path=Appli.AppName}"
                            FontSize="13"
                            HorizontalAlignment="Left"
                            TextWrapping="WrapWithOverflow"
                            Margin="0,0,0,1" />
                        <TextBlock
                            Text="{Binding Path=Appli.AppType}"
                            FontSize="9"
                            HorizontalAlignment="Left"
                            Margin="0,0,0,1" />
    
                    </StackPanel>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    
    </ListView>
    

    如果您希望用户能够在资源管理器和经典视图之间切换,只需定义第二个样式并切换列表视图的样式。例如,这可以通过一些 VisualStates 和“DataStateBehavior”来完成。

    或者,您可以使用一些 DataTriggers 和 Setter 为各个 ItemsPanel 创建一个样式。

    【讨论】:

    • 太棒了,谢谢,不敢相信我还没有考虑过为整个 ListView 设置样式。我想我会看看 DataStateBehavior 然后。再次感谢
    • 另一个相关问题:我不知道如何以预定义的样式定义ListView.GroupStyle。它应该是一个只读属性,我不知道如何定义它。有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多