ListView:在资源字典中定义ItemsPanelTemplate

发布于 2024-11-02 06:21:44 字数 2514 浏览 0 评论 0原文

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

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

我可以定义一个 ItemsPanelTemplate 来直接在 ListView.ItemsPanel 字段中正确地显示布局。现在,我想在资源中定义它,以便我能够在不同的视图中使用它,特别是在一个控件中,用户应该可以在资源管理器视图或经典列表视图之间进行选择(默认呈现为一个清单)

你是怎么做到的?我无法在我的 ResourceDictionary 中定义任何 ItemsPanelTemplate,并且如果我定义 DataTemplate 它是不兼容的(虽然我认为遵循纯逻辑,< code>ItemsPanelTemplate 应该继承自 DataTemplate,但实际上看起来并非如此)。

实际列表的代码片段:

<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,所以如果可能的话,我尽量不要使用代码隐藏

I have a ListView which layout looks like a Windows Explorer view (icon + some details), bound to a list somewhere in the ViewModel.

My aim here is to be able to switch between explorer view or classic view whenever we want.

I could define an ItemsPanelTemplate doing exactly the work to display correctly the layout, directly in the ListView.ItemsPanel field. Now, I'd like to define it in the resources so that I'll be able to use it in different views, and especially in one control, the user should have the choice between Explorer view or classic list view (the default rendering for a list)

How'd you do that? I cannot define any ItemsPanelTemplate in my ResourceDictionary, and if I define a DataTemplate it is not compatible (while I thought that following pure logic, ItemsPanelTemplate should inherit from DataTemplate, but it actually doesn't look like so).

Code snippet for the actual list:

<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>

Keeping the ItemTemplate in a static resource was easy to do, but now I can't do anything with the ItemsPanelTemplate...

Any ideas? I'm using MVVM so I'm trying ideally not to use code-behind if possible

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

放血 2024-11-09 06:21:44

为此,您可以为整个 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”来完成此操作。

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

You would use a style for the whole ListView for that. So you would do:

<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>

If you want the user then be able to switch between explorer and classic view, just define a second Style and switch the style of the listview. This can be done for example with some VisualStates and a 'DataStateBehavior'.

Alternatively you could create a style with some DataTriggers and Setters for the individual ItemsPanels.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文