我正在创建一个 DataGrid ,其功能与 Microsoft Dynamic Nav 相同。
这几乎就像一个Excel电子表格。
这个想法是你可以开始编辑一个单元格。完成后,有一些步骤:
根据列表验证单元格的内容
1.1如果列表包含给定的字符串(不区分大小写),则DataGrid中的内容将替换为列表中的字符串(也就是案例正确的字符串)。
1.2如果列表不包含字符串,它将显示一个可能的新表单,然后使用用户选择的表单替换已经键入DataGrid的表单。
如果用户输入了正确的内容或从列表中选择了正确的值,则DataGrid会自动使用预设字符串填充某些列
如果我们看一个例子:如果用户在第1列中键入z,那么我希望第2列变为“x”并将焦点移至colum3
DataGrid: (Before enter/Tab pressed)
[Column1] [Column2] [Column3] [Column4]
[ "a" ] [ "b" ] [ "c" ] [ "d" ]
[ "z" ] [ ] [ ] [ ]
(focused)
DataGrid: (Afture enter/tab pressed
[Column1] [Column2] [Column3] [Column4]
[ "a" ] [ "b" ] [ "c" ] [ "d" ]
[ "z" ] [ "x" ] [ ] [ ]
(focused)
在这里我遇到了一些问题:
CellEditEnding
事件来验证文本输入。如果我找到了正确的文本,那么我会在正确的变量上编辑currentItem
。但现在我需要调用dataGrid1.Items.Refresh();
而不是在编辑模式下完成。mycode的:
FormTest.xaml
...
<DataGrid.Columns>
<DataGridTextColumn Header="C1"
Binding="{Binding c1,UpdateSourceTrigger=LostFocus}"/>
<DataGridTextColumn Header="C2"
Binding="{Binding c2,UpdateSourceTrigger=LostFocus}"/>
<DataGridTextColumn Header="C3"
Binding="{Binding c3,UpdateSourceTrigger=LostFocus}"/>
<DataGridTextColumn Header="C4"
Binding="{Binding c4,UpdateSourceTrigger=LostFocus}"/>
<DataGridTextColumn Header="C5"
Binding="{Binding c5,UpdateSourceTrigger=LostFocus}"/>
</DataGrid.Columns>
...
FormTest.xaml.cs
public FormTest()
{
InitializeComponent();
loadMockData();
}
private void loadMockData()
{
dataItems = new DataItems();
dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
dataGrid1.ItemsSource = dataItems;
}
private void dataGrid1_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
TextBox editElement = e.EditingElement as TextBox;
DataItem di = dataGrid1.CurrentItem as DataItem;
DataGridCellInfo cell = dataGrid1.CurrentCell;
if (e.Column.DisplayIndex == 0)
{
if (editElement.Text == "z")
{
editElement.Text = "Z";
di.c1 = "Z";
di.c2 = "X";
}
}
}
private void dataGrid1_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter || e.Key == Key.Tab)
{
dataGrid1.CommitEdit();
DataItem di = dataGrid1.CurrentItem as DataItem;
dataGrid1.CancelEdit();
dataGrid1.Items.Refresh();
}
}
private class DataItems : List<DataItem> { }
private class DataItem
{
public int recID { get; set; }
public String c1 { get; set; }
public String c2 { get; set; }
public String c3 { get; set; }
public String c4 { get; set; }
public String c5 { get; set; }
}
调用刷新后,没有选定的单元格。这意味着如果不使用鼠标选择单元格,就无法继续输入数据。
当我开始输入新项目(又名空行),然后按Enter或Tab键时,dataGrid1.CancelEnding()
将删除新项目,并且该行再次为空。
ItemSoure
的情况下编辑数据网格的内容(Items.Refresh()
以及显示的内容)?Items.Refresh()
完成后设置单元格焦点。 ?答案 0 :(得分:0)
我可以回答有关更新网格内容的问题。
通常,在更改一个属性后不必刷新整个网格。 (如果您的网格中有大量数据,那也相当浪费。)如果您的班级DataItem
实现了INotifyPropertyChanged界面,并且您每次都会触发PropertyChanged
个事件其中一个属性更改后,WPF将自动更新表中的数据。
This page on MSDN包含实现此接口的示例,您可以找到使用此接口here的更完整示例。
这应该摆脱使用dataGrid1_PreviewKeyDown
事件处理程序的需要,而后者反过来解决了无法在网格底部添加新行的问题。
您还应该将Mode=TwoWay
添加到Binding
中的DataGridTextColumn
。否则,当您编辑单元格时,WPF将不会使用您在网格中输入的值更新相关的DataItem
对象。
在第一列中输入一个值之后,我看了第二列的“tab”方法,但是我没有找到任何有效的方法。