wpf ItemsControl 中的水平方向 WrapPanel 垂直列出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14803803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 07:27:30  来源:igfitidea点击:

Horizontal orientated WrapPanel within ItemsControl lists vertically

c#wpf.net-4.0itemscontrol

提问by Jamie Keeling

I have two DataTemplates defined within my XAML, each used for a seperate ItemsControl panel.

我在 XAML 中定义了两个 DataTemplates,每个都用于单独的 ItemsControl 面板。

The main ItemsControl lists Foo objects stored within an ObservableCollection object.

主要的 ItemsControl 列出了存储在 ObservableCollection 对象中的 Foo 对象。

The Foo object itself has its own set of items stored within as an ObservableCollection object.

Foo 对象本身具有作为 ObservableCollection 对象存储在其中的一组项目。

I tried to define the XAML in a way that allows for each of the ObservableCollection Foo items to be displayed with its name in a header (The first ItemsControl). From this the list within each Foo item itself should be displayed horizontally (Using the second ItemsControl) with a related field directly below. If enough items are present then they should wrap to the next line where necessary.

我尝试以一种允许每个 ObservableCollection Foo 项目与其名称一起显示在标题(第一个 ItemsControl)中的方式定义 XAML。由此,每个 Foo 项目本身中的列表应水平显示(使用第二个 ItemsControl),并在下方直接显示相关字段。如果存在足够的项目,则它们应在必要时换行到下一行。

This is how the UI currently stands:

这是 UI 目前的样子:

Incorrect UI

不正确的用户界面

This is how I wish the UI to actually appear:

这就是我希望 UI 实际出现的方式:

Correct UI

正确的用户界面

My Markup (Button controls are for another aspect of the UI) :

我的标记(按钮控件用于 UI 的另一个方面):

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
            <ItemsControl x:Name="ContentList" ItemTemplate="{StaticResource GameTemplate}" Grid.Column="0" />
        </ScrollViewer>
        <StackPanel Grid.Column="1" Background="DarkGray">
            <Button Click="OnLoad">_Load</Button>
            <Button Click="OnSave">_Save</Button>
            <Button Click="OnAdd">_Add</Button>
            <Button Click="OnDelete">_Delete</Button>
        </StackPanel>
    </Grid>

DataTemplate for listing Foo items:

用于列出 Foo 项目的数据模板:

<DataTemplate x:Key="GameTemplate">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="30" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Label Content="{Binding Name}" Grid.Row="0" Background="Gray" FontSize="16" />
                <ItemsControl x:Name="imageContent" 
                              ItemsSource="{Binding FileList}" 
                              ItemTemplate="{StaticResource GameImagesTemplate}" 
                              Grid.Row="1" />
            </Grid>
        </DataTemplate>

DataTemplate for listing items within each Foo item:

DataTemplate 用于列出每个 Foo 项目中的项目:

<DataTemplate x:Key="GameImagesTemplate">
            <WrapPanel Orientation="Horizontal">
                <StackPanel Orientation="Vertical" >
                    <Image Source="{Binding FileInfo.FullName}" 
                       Margin="8,8,8,8" 
                       Height="70" 
                       Width="70" />
                    <Label Content="{Binding Name}" />
                </StackPanel>
            </WrapPanel>
        </DataTemplate>

I'm fairly new to WPF so I have a feeling it's an issue caused by how I am using the controls.

我对 WPF 还很陌生,所以我觉得这是我使用控件的方式引起的问题。

What WPF changes would I need to make in order to generate the UI I would like?

我需要对 WPF 进行哪些更改才能生成我想要的 UI?

回答by sa_ddam213

I think its because you are adding each image item to a new WrapPanelin GameImagesTemplate, you should just have to set the ItemsControlItemsPanelTemplateto WrapPanelin the GameTemplate

我认为它是因为你添加的每个图像项到一个新WrapPanelGameImagesTemplate,你应该只需要设置ItemsControlItemsPanelTemplateWrapPanelGameTemplate

Example:

例子:

Xaml:

Xml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="252.351" Width="403.213" Name="UI" >
    <Window.Resources>

        <DataTemplate x:Key="GameImagesTemplate" >
            <StackPanel>
                <Image Source="{Binding FileInfo.FullName}" Margin="8,8,8,8" Height="70" Width="70" />
                <Label Content="{Binding Name}" />
            </StackPanel>
        </DataTemplate>

        <DataTemplate x:Key="GameTemplate">
            <StackPanel>
                <Label Content="{Binding Name}" Grid.Row="0" Background="Gray" FontSize="16" />
                <ItemsControl x:Name="imageContent" ItemsSource="{Binding FileList}" ItemTemplate="{StaticResource GameImagesTemplate}" >
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
            <ItemsControl ItemsSource="{Binding ElementName=UI, Path=FileList}" Grid.Column="0" ItemTemplate="{StaticResource GameTemplate}" />
        </ScrollViewer>
    </Grid>
</Window>

Code:

代码:

public partial class MainWindow : Window
{
    private ObservableCollection<Foo> _fileList = new ObservableCollection<Foo>();

    public MainWindow()
    {
        InitializeComponent();
        foreach (var item in Directory.GetDirectories(@"C:\StackOverflow"))
        {
            FileList.Add(new Foo
            {
                Name = item,
                FileList = new ObservableCollection<Bar>(Directory.GetFiles(item).Select(x => new Bar { FileInfo = new FileInfo(x) }))
            });
        }
    } 

    public ObservableCollection<Foo> FileList
    {
        get { return _fileList; }
        set { _fileList = value; }
    }
}

public class Foo
{
    public string Name { get; set; }
    public ObservableCollection<Bar> FileList { get; set; }
}

public class Bar
{
    public FileInfo FileInfo { get; set; }
}

Result

结果

enter image description here

在此处输入图片说明