动态添加填充了绑定文本框的网格行

时间:2016-12-06 16:43:51

标签: c# wpf mvvm wpfgrid

我最近完成了我的第一个MVVM样式应用程序,其中包含一定数量的列/行和控件。

我现在要做的是,根据observableCollection<myClass>中的项目数,在主网格中添加一行,这些行填充了与observableCollection的每个项目中的属性绑定的文本框。< / p>

例如,这里是一个viewmodel示例:

public class VehiclesViewModel : ObservableObject
{
    private ObservableCollection<Vehicle> _vehCollection;
    public ObservableCollection<Vehicle> VehCollection
    {
        get
        {
            return this._vehCollection;
        }

        set
        {
            if (null != value)
            {
                this._vehCollection= value;
                OnPropertyChanged("VehCollection");
            }
        }
    }
}

这是模型类:

public class Vehicle : INotifyPropertyChanged
{

    private double _alt;
    public double Alt 
    {
        get { return this._alt; }
        set
        {
            this._alt = value;
            base.OnPropertyChanged("Alt");
        }
    }

    private double _depth;        
    public string Depth
    {
        get { return this._depth; }
        set
        {
            this._depth = value;
            base.OnPropertyChanged("Depth");
        }
    }
}

以下是一个示例视图:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="39.8" />
        <ColumnDefinition Width="39.8" />
        <ColumnDefinition Width="80" />
        <ColumnDefinition Width="80" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="26" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <ItemsControl ItemsSource="{Binding VehCollection}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBox Text="{Binding Alt}" Grid.Column="0" Grid.ColumnSpan="2"/>
                    <TextBox Text="{Binding Depth}"
                            Grid.Column="3"
                            Grid.ColumnSpan="2" />
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

让我们说我调用的一些功能会将三个项添加到_vehCollection中。发生这种情况时,我希望网格在现有行下面添加三个行,其中每个行包含两个文本框,这些文本框绑定到我的Vehicle类中的每个项目的属性。我还想指定它们将出现的Grid.Column(它们将水平显示在同一行,而不是垂直显示)。

我尝试使用ItemsControl,这会使文本框显示,但它出现在网格的左上角。我无法将其显示在现有行下方。

注意:我在主网格中有更多行/列定义和其他控件。我不想重做所有这些。

2 个答案:

答案 0 :(得分:1)

您可以使用带有Grid的ItemsControl作为其ItemPanel。但是,将RowDefinitions动态添加到Grid中会有点棘手。请查看以下博文,了解更多信息和示例:http://blog.scottlogic.com/2010/11/15/using-a-grid-as-the-panel-for-an-itemscontrol.html

更简单的方法是使用带有ItemTemplate的ItemsControl,其中包含具有所需列数的Grid。然后,您可以将类型为int的Column属性添加到Vehicle类,并将ItemTemplate中StackPanel的Grid.Column附加属性绑定到此类:

     <ItemsControl ItemsSource="{Binding VehCollection}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="39.8" />
                        <ColumnDefinition Width="39.8" />
                        <ColumnDefinition Width="80"  />
                        <ColumnDefinition Width="80" />
                    </Grid.ColumnDefinitions>
                    <StackPanel Orientation="Horizontal" Grid.Column="{Binding Column}">
                        <TextBox Text="{Binding Alt}" />
                        <TextBox Text="{Binding Depth}" />
                    </StackPanel>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

如果每个TextBox都应该在它自己的列中,你可以为每个TextBox添加一个“Column”属性到你的Vehicle类并分别绑定到这些:

<TextBox Text="{Binding Alt}" Grid.Column="{Binding AltColumn}" />
<TextBox Text="{Binding Depth}" Grid.Column="{Binding Deptholumn}" />

答案 1 :(得分:1)

确定你的Items控件正在做的是显示0,0网格单元格中的项目列表

你需要的是将网格放在列表中最简单的方法是GridView

例如

<ListView ItemsSource="{Binding VehCollection}">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Depth}"/>
            <GridViewColumn DisplayMemberBinding="{Binding Alt}"/>
            <GridViewColumn/>
            <GridViewColumn/>
        </GridView>
    </ListView.View>

另一种选择是将项目模板设置为网格

<ItemsControl ItemsSource="{Binding VehCollection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="39.8" />
                    <ColumnDefinition Width="39.8" />
                    <ColumnDefinition Width="80"  />
                    <ColumnDefinition Width="80" />
                </Grid.ColumnDefinitions>
                <TextBox Text="{Binding Alt}" Grid.Column="0"/>
                <TextBox Text="{Binding Depth}"  Grid.Column="1"/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>