c# - 动态添加填充有绑定(bind)文本框的网格行

标签 c# wpf mvvm wpf-grid

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

我现在要做的是,基于 observableCollection<myClass> 中的项目数,在主网格中添加一行,其中填充了绑定(bind)到 observableCollection 的每个项目中的属性的文本框。

因此,例如,这是一个 View 模型示例:

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

这是一个示例 View :
<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 的项目。发生这种情况时,我希望网格添加 现有行下方的行,这三个行中的每一个都包含两个文本框,这些文本框绑定(bind)到我的 Vehicle 类中每个项目的属性。我还想指定 Grid.Column它们将出现在(它们将水平出现在同一行,而不是垂直出现)。

我尝试使用 ItemsControl ,这确实使文本框出现,但它出现在网格的左上角。我无法让它出现在现有行的下方。

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

最佳答案

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

一种更简单的方法是将 ItemsControl 与 ItemTemplate 一起使用,其中包含具有所需列数的 Grid。然后,您可以将 int 类型的 Column 属性添加到您的 Vehicle 类中,并将 ItemTemplate 中 StackPanel 的 Grid.Column 附加属性绑定(bind)到这个:

     <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 类并分别绑定(bind)到这些:
<TextBox Text="{Binding Alt}" Grid.Column="{Binding AltColumn}" />
<TextBox Text="{Binding Depth}" Grid.Column="{Binding Deptholumn}" />

关于c# - 动态添加填充有绑定(bind)文本框的网格行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41000514/

相关文章:

c# - 无法跟踪类型实体,因为主键属性 'id' 为空

c# - 种子方法未在已发布的 IIS 上触发

wpf - 如何从我的 ViewModel 跟踪选定的 TabPage 的 DataContext?

C# WPF - 如何修改 ToolBar.ButtonStyleKey 样式

c# - .NET 程序在什么情况下会终止?

c# - XNA C# 2D 平台游戏

c# - 如何将一种类型的通用列表转换为未知类型的通用列表

mvvm - 根据不同的数据绑定(bind)到自定义构建的控件

wpf - 如何重复使用相同的控件两次但保持它们之间的状态

c# - 使用 IoC 将参数从 ViewModel 传递到另一个