0

我想用动态网格构建一个 ui。至少我认为网格是要走的路。每个单元格的控件应该相同,fe a TextBox

每行可以有不同数量的单元格,我考虑使用该ColumnSpan属性使 ui 看起来像

First row, 2 cells
Second row, 3 cells
Third row, 1 cell

每个单元格都应该是 fe 的一部分,ObservableCollection<MyCellClass>并且应该具有Row, Column, Columnspan,等属性Text

我知道如何构建动态网格,但我不知道如何通过模板设置单元格的内容以及如何对文本框进行数据绑定。

也许我的方法不是最好的,你有其他想法来解决我的问题。

4

2 回答 2

2

您可以使用 Grid 作为ItemsPanelItemsControl 的,并将ItemsSource属性绑定到您的 ObservableCollection。

假设您的单元格类如下所示:

public class Cell
{
    public int Column { get; set; }
    public int ColumnSpan { get; set; }
    public int Row { get; set; }
    public int RowSpan { get; set; }
    public string Text { get; set; }
}

XAML 可以写成如下所示:

<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Grid.Column" Value="{Binding Column}"/>
            <Setter Property="Grid.ColumnSpan" Value="{Binding ColumnSpan}"/>
            <Setter Property="Grid.Row" Value="{Binding Row}"/>
            <Setter Property="Grid.RowSpan" Value="{Binding RowSpan}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Text}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

以下代码将初始化 ItemsControl 的两个单元格:

public MainWindow()
{
    InitializeComponent();

    var cells = new ObservableCollection<Cell>();
    cells.Add(new Cell { Column = 0, Row = 0, ColumnSpan = 1, RowSpan = 1, Text = "Cell 1" });
    cells.Add(new Cell { Column = 2, Row = 2, ColumnSpan = 2, RowSpan = 1, Text = "Cell 2" });
    DataContext = cells;
}
于 2013-05-16T10:34:42.633 回答
0

为什么不使用这样的东西?

public class ItemVm 
{
    // here you can put your desired properties, 
    // although you won't need something like ColumnsSpan etc.
}

作为网格的底层结构(视图模型),您可以使用以下属性:

public ObservableCollection<ObservableCollection<ItemVm>> Rows { get; } // just an illustration

现在你只需要一个ListView(或类似的东西),它又ItemTemplate是一个ListView(或类似的东西)。ItemTemplate内部的将ListView是 的视觉表示ItemVm

请注意,我正在根据 MVVM 模式描述一种方法。所以你需要一个视图模型的基类。但是你可以在 WWW 上找到很多框架。

于 2013-05-16T09:51:15.827 回答