将空白行插入到具有动态列的数据网格中
Insert a blank row into a Datagrid with dynamic columns
我在后面的代码中使用列表动态创建 Silverlight DataGrid 的列,如下所示:
private void BuildQuotationDGColumns(List<ProductCategory> ProdCatList)
{
// add a template column with drop down list of products
DataGridTemplateColumn ProductColumn = new DataGridTemplateColumn();
ProductColumn.Header="Choose Product";
ProductColumn.CellTemplate=(DataTemplate) Resources["ProductDDLTemplate"];
QuotationDG.Columns.Add(ProductColumn);
// for each entity in ProdCatList add a text column
foreach (ProductCategory ProdCat in ProdCatList)
{
DataGridTemplateColumn ProdCatColumn = new DataGridTemplateColumn();
ProdCatColumn.Header = ProdCat.Name;
ProdCatColumn.CellTemplate = (DataTemplate)Resources["MoneyTemplate"];
ProdCatColumn.CellEditingTemplate = (DataTemplate)Resources["MoneyEditingTemplate"];
QuotationDG.Columns.Add(ProdCatColumn);
}
insertDummyRow(ProdCatList);
}
我需要使用 insertDummyRow 在我的 Datagrid 中插入一个空白行。由于列是动态的并且仅在 运行 时间内已知,因此我需要创建一个实体,其属性可在 运行 时间内设置。
我想将我的 ProdCatList 转换为 Class,这样 class 的实例将形成网格行,但我不明白如何进行此转换
编辑:
基于下面Bahman_Aries的解决方案,
我正在尝试将数据添加到我的行中,但我得到的是空行,并且我的数据 (column.Header.ToString()) 未添加。这是我的代码:
CultureInfo provider= new CultureInfo("en-US");
Object[] myrow= new Object[QuotationDG.Columns.Count];
int i=0;
foreach(DataGridColumn column in QuotationDG.Columns)
{
myrow[i] = Convert.ChangeType(column.Header.ToString(), typeof(object), provider);
i++;
}
MyData.Add(myrow);
QuotationDG.ItemsSource = MyData;
你能指出我做错了什么吗?
这是网格模板的实现:
<UserControl.Resources>
<DataTemplate x:Key="MoneyTemplate">
<TextBlock></TextBlock>
</DataTemplate>
<DataTemplate x:Key="MoneyEditingTemplate">
<TextBlock></TextBlock>
</DataTemplate>
<DataTemplate x:Key="ProductDDLTemplate">
<ComboBox />
</DataTemplate>
</UserControl.Resources>
好的,让我在继续之前澄清一些困惑:
Since the columns are dynamic and are only known in runtime, I need to
create an entity whose attributes can be set in run time.
不一定,可以用objects
.
的列表
I thought of converting my ProdCatList into a Class, so that instances
of this class would form the grid rows
无需创建复杂的数据结构,只需将空白行插入 DataGrid
,像 QuotationDG.Items.Add("");
这样简单的操作即可。
所以据我了解,要么你把问题过于复杂化了,要么你没有提供足够的信息,我把它简单化了! (如果是这样,请告诉我,以便我可以立即更正)。
无论如何,既然你定义了一个 CellEditingTemplate
我假设你的网格单元格是可编辑的,因此你不能使用 QuotationDG.Items.Add
因为它会阻止编辑。相反,您应该定义一个列表,将数据添加到其中,然后将其用作 DataGrid
:
的 ItemsSource
// Your data source
ObservableCollection<object[]> MyData = new ObservableCollection<object[]>();
// Insert a blank row into the data source
private void insertDummyRow()
{
MyData.Add(new object[QuotationDG.Columns.Count]);
QuotationDG.ItemsSource = MyData;
}
编辑:
由于您的 CellTemplates
中没有数据绑定,因此您的 DataGrid
中看不到任何内容。为此,当动态创建列时,您还需要添加相应的 DataBindings
:
// Sample drop down list of products to show
public ObservableCollection<string> ProductList = new ObservableCollection<string> { "Item1", "Item2", "Item3" };
private void BuildQuotationDGColumns(List<ProductCategory> ProdCatList)
{
// Define a DataGridComboBoxColumn
DataGridComboBoxColumn prodComboColumn = new DataGridComboBoxColumn();
// Bind this column to the first item of the DataGrid.ItemsSource (e.g. MyData[0])
prodComboColumn.SelectedItemBinding = new Binding("[0]");
// Set ProductList as the ItemsSource of DataGridComboBoxColumn
prodComboColumn.ItemsSource = ProductList;
prodComboColumn.Header = "Choose Product";
QuotationDG.Columns.Add(prodComboColumn);
// For each entity in ProdCatList add a text column
int i = 1;
foreach (ProductCategory ProdCat in ProdCatList)
{
// Define a DataGridTextColumn
DataGridTextColumn ProdCatColumn = new DataGridTextColumn();
ProdCatColumn.Header = ProdCat.Name;
// Bind this column to the i-th item of the DataGrid.ItemsSource (e.g. MyData[i])
ProdCatColumn.Binding = new Binding(string.Format("[{0}]", i));
QuotationDG.Columns.Add(ProdCatColumn);
i++;
}
insertDummyRow();
}
要查看 UI 是否显示任何数据,您可以尝试我对您的添加数据程序的修改版本:
private void Button_Click(object sender, RoutedEventArgs e)
{
CultureInfo provider = new CultureInfo("en-US");
Object[] myrow = new Object[QuotationDG.Columns.Count];
int i = 0;
foreach (DataGridColumn column in QuotationDG.Columns)
{
if (column is DataGridComboBoxColumn)
myrow[i] = Convert.ChangeType(ProductList[0], typeof(object), provider);
else
myrow[i] = Convert.ChangeType(column.Header.ToString(), typeof(object), provider);
i++;
}
MyData.Add(myrow);
QuotationDG.ItemsSource = MyData;
}
为确保用户输入的数据也将更新源(例如 MyData
),请设置一个断点并在编辑数据网格后检查 MyData
是否有任何更改手动单元格。
我在后面的代码中使用列表动态创建 Silverlight DataGrid 的列,如下所示:
private void BuildQuotationDGColumns(List<ProductCategory> ProdCatList)
{
// add a template column with drop down list of products
DataGridTemplateColumn ProductColumn = new DataGridTemplateColumn();
ProductColumn.Header="Choose Product";
ProductColumn.CellTemplate=(DataTemplate) Resources["ProductDDLTemplate"];
QuotationDG.Columns.Add(ProductColumn);
// for each entity in ProdCatList add a text column
foreach (ProductCategory ProdCat in ProdCatList)
{
DataGridTemplateColumn ProdCatColumn = new DataGridTemplateColumn();
ProdCatColumn.Header = ProdCat.Name;
ProdCatColumn.CellTemplate = (DataTemplate)Resources["MoneyTemplate"];
ProdCatColumn.CellEditingTemplate = (DataTemplate)Resources["MoneyEditingTemplate"];
QuotationDG.Columns.Add(ProdCatColumn);
}
insertDummyRow(ProdCatList);
}
我需要使用 insertDummyRow 在我的 Datagrid 中插入一个空白行。由于列是动态的并且仅在 运行 时间内已知,因此我需要创建一个实体,其属性可在 运行 时间内设置。
我想将我的 ProdCatList 转换为 Class,这样 class 的实例将形成网格行,但我不明白如何进行此转换
编辑:
基于下面Bahman_Aries的解决方案, 我正在尝试将数据添加到我的行中,但我得到的是空行,并且我的数据 (column.Header.ToString()) 未添加。这是我的代码:
CultureInfo provider= new CultureInfo("en-US");
Object[] myrow= new Object[QuotationDG.Columns.Count];
int i=0;
foreach(DataGridColumn column in QuotationDG.Columns)
{
myrow[i] = Convert.ChangeType(column.Header.ToString(), typeof(object), provider);
i++;
}
MyData.Add(myrow);
QuotationDG.ItemsSource = MyData;
你能指出我做错了什么吗?
这是网格模板的实现:
<UserControl.Resources>
<DataTemplate x:Key="MoneyTemplate">
<TextBlock></TextBlock>
</DataTemplate>
<DataTemplate x:Key="MoneyEditingTemplate">
<TextBlock></TextBlock>
</DataTemplate>
<DataTemplate x:Key="ProductDDLTemplate">
<ComboBox />
</DataTemplate>
</UserControl.Resources>
好的,让我在继续之前澄清一些困惑:
Since the columns are dynamic and are only known in runtime, I need to create an entity whose attributes can be set in run time.
不一定,可以用objects
.
I thought of converting my ProdCatList into a Class, so that instances of this class would form the grid rows
无需创建复杂的数据结构,只需将空白行插入 DataGrid
,像 QuotationDG.Items.Add("");
这样简单的操作即可。
所以据我了解,要么你把问题过于复杂化了,要么你没有提供足够的信息,我把它简单化了! (如果是这样,请告诉我,以便我可以立即更正)。
无论如何,既然你定义了一个 CellEditingTemplate
我假设你的网格单元格是可编辑的,因此你不能使用 QuotationDG.Items.Add
因为它会阻止编辑。相反,您应该定义一个列表,将数据添加到其中,然后将其用作 DataGrid
:
ItemsSource
// Your data source
ObservableCollection<object[]> MyData = new ObservableCollection<object[]>();
// Insert a blank row into the data source
private void insertDummyRow()
{
MyData.Add(new object[QuotationDG.Columns.Count]);
QuotationDG.ItemsSource = MyData;
}
编辑:
由于您的 CellTemplates
中没有数据绑定,因此您的 DataGrid
中看不到任何内容。为此,当动态创建列时,您还需要添加相应的 DataBindings
:
// Sample drop down list of products to show
public ObservableCollection<string> ProductList = new ObservableCollection<string> { "Item1", "Item2", "Item3" };
private void BuildQuotationDGColumns(List<ProductCategory> ProdCatList)
{
// Define a DataGridComboBoxColumn
DataGridComboBoxColumn prodComboColumn = new DataGridComboBoxColumn();
// Bind this column to the first item of the DataGrid.ItemsSource (e.g. MyData[0])
prodComboColumn.SelectedItemBinding = new Binding("[0]");
// Set ProductList as the ItemsSource of DataGridComboBoxColumn
prodComboColumn.ItemsSource = ProductList;
prodComboColumn.Header = "Choose Product";
QuotationDG.Columns.Add(prodComboColumn);
// For each entity in ProdCatList add a text column
int i = 1;
foreach (ProductCategory ProdCat in ProdCatList)
{
// Define a DataGridTextColumn
DataGridTextColumn ProdCatColumn = new DataGridTextColumn();
ProdCatColumn.Header = ProdCat.Name;
// Bind this column to the i-th item of the DataGrid.ItemsSource (e.g. MyData[i])
ProdCatColumn.Binding = new Binding(string.Format("[{0}]", i));
QuotationDG.Columns.Add(ProdCatColumn);
i++;
}
insertDummyRow();
}
要查看 UI 是否显示任何数据,您可以尝试我对您的添加数据程序的修改版本:
private void Button_Click(object sender, RoutedEventArgs e)
{
CultureInfo provider = new CultureInfo("en-US");
Object[] myrow = new Object[QuotationDG.Columns.Count];
int i = 0;
foreach (DataGridColumn column in QuotationDG.Columns)
{
if (column is DataGridComboBoxColumn)
myrow[i] = Convert.ChangeType(ProductList[0], typeof(object), provider);
else
myrow[i] = Convert.ChangeType(column.Header.ToString(), typeof(object), provider);
i++;
}
MyData.Add(myrow);
QuotationDG.ItemsSource = MyData;
}
为确保用户输入的数据也将更新源(例如 MyData
),请设置一个断点并在编辑数据网格后检查 MyData
是否有任何更改手动单元格。