c# - ItemsControl 中的水平定向 WrapPanel 垂直列表

标签 c# wpf .net-4.0 itemscontrol

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

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

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

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

这是 UI 目前的样子:

Incorrect UI

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

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

用于列出 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>

用于在每个 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>

我是 WPF 的新手,所以我觉得这是我使用控件的方式引起的问题。

为了生成我想要的 UI,我需要对 WPF 进行哪些更改?

最佳答案

我认为这是因为您要将每个图像项添加到 GameImagesTemplate 中的新 WrapPanel 中,您只需要设置 ItemsControl ItemsPanelTemplateGameTemplate

中的 WrapPanel

示例:

Xaml:

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

代码:

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

结果

enter image description here

关于c# - ItemsControl 中的水平定向 WrapPanel 垂直列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14803803/

相关文章:

c# - ASP.NET Core 3.1 - WebApplicationFactory - WebApplicationFactoryContentRootAttribute 的正确用法是什么?

wpf - 在 DataTemplate 中绑定(bind) Grid.Row/Grid.Column

wpf - 如何将列高限制为另一个?

c# - 未知服务器标签 'CR:CrystalReportViewer'

c# - 如何制作类似聊天的界面/显示?

c# - C# 中基于 XML 的项目文件的设计模式

c# - 我们可以创建名称为 "class"的类吗?

c# - 使 FlowDocument 光标在 RichTextBox 中垂直居中

c# - 抛出 WebException 的代码在 .NET 3.5 中有效,但在 4.0 中无效

c# - 从 Session 中清理非托管资源,如 Crystal Report Document