WPF:如何创建自定义项目控制面板?

发布于 2024-10-09 11:06:07 字数 719 浏览 7 评论 0原文

我想为 ListBox 设计一个自定义项目控制面板。有 3 个要求:

  1. 它应该具有属性 int rowsint columns,它们将定义面板组成的单元格矩阵。这就是面板的样子(颜色无关紧要,我只是想表明面板由 3x4 矩阵中的 12 个空单元组成): alt text

  2. 如果项目控件中的项目数小于定义的单元格数,则所有单元格应被绘制。例如,如果如图所示的 3x4 矩阵中仅放置 4 个项目,则应绘制所有单元格,并且其中只有 4 个单元格应包含这些项目。

  3. 应该可以通过某些数据绑定来设置哪个单元格将托管哪个项目。例如,假设我有一份人员名单。该列表包含 Person 类型的项目,并且 Person 类包含两个属性 XY。我应该能够将 X 数据绑定到单元格的 row 并将 Y 数据绑定到单元格的 column ,从而允许我自己设置面板中的哪个单元格将包含列表中的哪个人。

如果创建项目控制面板没有意义,请推荐更好的方法。老实说,我对如何开始这件事感到困惑。感谢您的所有帮助。干杯!

I want to design a custom items control panel for a ListBox. There are 3 requirements:

  1. It should have the properties int rows and int columns which would define the matrix of cells that the panel is made of. This is what the panel should look like (colors are irrelevant, I just wanted to show that the panel is consisted of 12 empty cells in a 3x4 matrix):
    alt text

  2. If the number of items in the items control is less than the number of defined cells all the cells should be drawn. E.g. if there are only 4 items to be placed in a 3x4 matrix shown in the picture, all of the cells should be drawn and only 4 of them should contain the items.

  3. It should be possible to set which cell will host which item, via some data binding. For example, let's say I had a list of persons. That list contains items of type Person and the Person class contains two properties X and Y. I should be able to data bind X to the row of the cell and Y to the column of the cell, thus allowing myself to set which cell in the panel will contain which person from the list.

If creating the items control panel doesn't make sense, please recommend what would be the better approach. To be quite honest I am puzzled on how to even get started with this. Thanks for all the help. Cheers!

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

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

发布评论

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

评论(1

夜夜流光相皎洁 2024-10-16 11:06:07

解决此类问题的一个有用策略是将源数据处理为更适合 ItemsControl 使用的格式。例如,项目的二维数组或包含其自己的二维坐标的项目的线性集合很难利用。

相反,通过简单的数据结构转换,您可以将 ItemsSource 绑定到集合的集合。外部集合包含三行,每个内部集合包含四个项目。每个项目都可以包含其实际的行和列坐标,并且可以处理相应的单元格是否应显示任何数据。

这是一个 2x2 的示例,向您展示我的意思:

<Grid>
    <Grid.Resources>
        <coll:ArrayList x:Key="sampleData">
            <x:Array Type="sys:String">
                <sys:String>1</sys:String><sys:String>2</sys:String>
            </x:Array>
            <x:Array Type="sys:String">
                <sys:String>3</sys:String<sys:String>4</sys:String>
            </x:Array>
        </coll:ArrayList>
    </Grid.Resources>
    <ItemsControl ItemsSource="{StaticResource sampleData}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ItemsControl ItemsSource="{Binding}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Border BorderBrush="Black" BorderThickness="1" Width="50" Height="50">
                                <TextBlock Text="{Binding}"/>
                            </Border>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

它会产生:

+---+---+
| 1 | 2 |
+---+---+
| 3 | 4 |
+---+---+

A useful strategy to solve this kind of problem is to manipulate the source data into a format more suitable for consumption by an ItemsControl. For example, a two-dimensional array of items, or a linear collection of items that contain their own two-dimensional coordinates, is hard to utilize.

Instead, with a simple data structure transformation you can bind your ItemsSource to collection of collections. The outer collection contains three rows and each inner collection contains four items. Each item can contain its actual row and column coordinates and can handle whether the corresponding cell should display any data.

Here's a 2x2 example to show you what I mean:

<Grid>
    <Grid.Resources>
        <coll:ArrayList x:Key="sampleData">
            <x:Array Type="sys:String">
                <sys:String>1</sys:String><sys:String>2</sys:String>
            </x:Array>
            <x:Array Type="sys:String">
                <sys:String>3</sys:String<sys:String>4</sys:String>
            </x:Array>
        </coll:ArrayList>
    </Grid.Resources>
    <ItemsControl ItemsSource="{StaticResource sampleData}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ItemsControl ItemsSource="{Binding}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Border BorderBrush="Black" BorderThickness="1" Width="50" Height="50">
                                <TextBlock Text="{Binding}"/>
                            </Border>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

which produces:

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