嗯,我的last question没有得到任何回应,除了一个downvote,所以我打算分解这个问题并一次提出一个基本问题。
我有一个WPF应用程序,其中有一个Grid(不是DataGrid)。现在我想在运行时向它添加行。并且在每个行中都将是TextBox或Combobox之类的控件。我理解这可以通过RowDefinitions.Add(New RowDefinition())
完成,然后向行中的每个单元格添加单独的控件,就像我们在WinForms中的TableLayoutPanel中所做的那样。但我正在寻找一种更优雅的解决方案,当点击按钮或触发事件时,所有带有事件处理程序的控件都将添加到Grid的新行中的相应单元格中。有没有简单的方法呢?
P.S。我还需要根据需要删除行,如果这是一个因素。删除的行并不总是最后一行。
答案 0 :(得分:0)
通常情况下,最好使用DataGrid显示重复行的数据,而不是 一个网格。但是如果你有特殊的理由使用Grid,我已经使用Grid附加了一个代码示例,每行显示一个Textbox,一个ComboBox和一个DeleteButton。 “添加”按钮允许在底部添加新行,每行的DeleteButtons允许删除该行。
XAML:
<Window x:Class="GridAddRow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:GridAddRow"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<Grid Name="MainGrid" DockPanel.Dock="Top"/>
<Button DockPanel.Dock="Top" Name="AddButton" Content="Add"/>
<Rectangle Fill="Gainsboro"/>
</DockPanel>
</Window>
C#:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace GridAddRow {
public partial class MainWindow: Window {
int textCol, comboBoxCol, buttonCol;
public MainWindow() {
InitializeComponent();
//initialise MainGrid, i.e. define columns, could be done in XAML
addCol(out textCol, new GridLength(100));
addCol(out comboBoxCol, GridLength.Auto);
addCol(out buttonCol, GridLength.Auto);
//initialise grid content, usually read from a db
addRow("Some Text", 1);
addRow("Another String", 3);
AddButton.Click += AddButton_Click;
}
private void addCol(out int textCol, GridLength gridLength) {
textCol = MainGrid.ColumnDefinitions.Count;
MainGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = gridLength });
}
List<TextBox> textBoxes = new List<TextBox>();
List<ComboBox> comboBoxes = new List<ComboBox>();
private void addRow(string textBoxString, int comboBoxIndex) {
int rowId = MainGrid.RowDefinitions.Count;
MainGrid.RowDefinitions.Add(new RowDefinition());
TextBox textBox = new TextBox { Text = textBoxString };
textBoxes.Add(textBox);
addControl(textBox, rowId, textCol);
textBox.TextChanged += TextBox_TextChanged;
ComboBox comboBox = new ComboBox {SelectedIndex= comboBoxIndex };
comboBox.Items.Add(new ComboBoxItem {Content="0" });
comboBox.Items.Add(new ComboBoxItem { Content="1" });
comboBox.Items.Add(new ComboBoxItem { Content="2" });
comboBox.Items.Add(new ComboBoxItem { Content="3" });
comboBoxes.Add(comboBox);
addControl(comboBox, rowId, comboBoxCol);
comboBox.SelectionChanged += ComboBox_SelectionChanged;
Button deleteRowButton = new Button {Content = "Delete"};
addControl(deleteRowButton, rowId, buttonCol);
deleteRowButton.Click += DeleteRowButton_Click;
}
private void addControl(Control control, int rowId, int textCol) {
control.Tag = rowId;
MainGrid.Children.Add(control);
Grid.SetRow(control, rowId);
Grid.SetColumn(control, textCol);
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
TextBox textbox = (TextBox)sender;
int rowid = (int)textbox.Tag;
//do something here.
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
ComboBox comboBox = (ComboBox)sender;
int rowid = (int)comboBox.Tag;
//do something here.
}
private void DeleteRowButton_Click(object sender, RoutedEventArgs e) {
Button deleteButton = (Button)sender;
int rowid = (int)deleteButton.Tag;
MainGrid.Children.Remove(deleteButton);
TextBox textbox = textBoxes[rowid];
MainGrid.Children.Remove(textbox);
textBoxes.RemoveAt(rowid);
ComboBox comboBox = comboBoxes[rowid];
MainGrid.Children.Remove(comboBox);
comboBoxes.RemoveAt(rowid);
}
private void AddButton_Click(object sender, RoutedEventArgs e) {
addRow("", 1);
}
}
}
说&#34;你应该使用MVVM&#34;基本上只是意味着你应该为你在Window中使用的每个控件(Textbox,Combobox)创建一个具有一个属性的类。使用要显示的数据创建该类的集合,然后将其绑定到DataGrid,DataGrid将显示数据并提供许多功能,您必须在使用Grid时自行编程。有关详细信息,请参阅我的文章:Guide to WPF DataGrid formatting using bindings