动态ui,包含行和列

时间:2013-05-16 08:14:14

标签: wpf mvvm

我想用动态网格构建一个ui。至少我认为网格是要走的路。 每个细胞的控制应该是相同的,例如。一个TextBox

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

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

每个细胞应该是f.e.的一部分。 ObservableCollection<MyCellClass>并且应该包含RowColumnColumnspanText等属性。

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

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

2 个答案:

答案 0 :(得分:2)

您可以使用Grid作为ItemsControl的ItemsPanel,并将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;
}

答案 1 :(得分:0)

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

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

作为网格的基础结构(viewmodel),您可以使用以下属性:

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

现在您只需ListView(或类似的东西),其ItemTemplate又是ListView(或类似的东西)。内部ItemTemplate的{​​{1}}将是ListView的直观表示。

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