Динамическое добавление строк сетки, заполненных связанными текстовыми полями
Я недавно закончил свое первое приложение в стиле MVVM, в котором было заданное количество столбцов / строк и элементов управления.
То, что я пытаюсь сделать сейчас, основано на количестве элементов в observableCollection<myClass>
добавьте строку в основную сетку, заполненную текстовыми полями, привязанными к свойствам в каждом элементе observableCollection.
Так, например, вот пример модели представления:
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 ответа
Вы можете использовать ItemsControl с Grid в качестве ItemPanel. Хотя будет немного сложнее динамически добавить RowDefinitions в Grid. Пожалуйста, ознакомьтесь со следующим сообщением в блоге для получения дополнительной информации и примера: http://blog.scottlogic.com/2010/11/15/using-a-grid-as-the-panel-for-an-itemscontrol.html.
Более простой подход - использовать ItemsControl с ItemTemplate, который содержит Grid с нужным количеством столбцов. Затем вы можете добавить свойство Column типа int в свой класс Vehicle и связать вложенное свойство Grid.Column вашей StackPanel в ItemTemplate с этим:
<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 должен быть в своем собственном столбце, вы можете добавить свойство "Column" для каждого TextBox в свой класс Vehicle и привязать их по отдельности:
<TextBox Text="{Binding Alt}" Grid.Column="{Binding AltColumn}" />
<TextBox Text="{Binding Depth}" Grid.Column="{Binding Deptholumn}" />
Хорошо, что делает ваш элемент управления, говорит, показать список элементов в ячейке сетки 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>