我的XAML:
<Window x:Class="DataGridSelectionDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataGrid selection demo" Height="350" Width="525">
<Grid>
<DataGrid x:Name="dataGridEmp" CellEditEnding="OnDataGridCellEditEnding"
AutoGenerateColumns="False"
DockPanel.Dock="Top"
ItemsSource="{Binding}">
<DataGrid.Columns>
<DataGridTextColumn x:Name="Code" Header="Code" Width="60" Binding="{Binding Path=Code, Mode=TwoWay}" />
<DataGridTextColumn x:Name="Name" Header="Name" Width="200" Binding="{Binding Path=Name, Mode=TwoWay}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
我的代码后面:
{
public class Employee
{
public string Code { get; set; }
public string Name { get; set; }
}
private ObservableCollection<Employee> EmpCollection =
new ObservableCollection<Employee>
{
new Employee {Code = "E004", Name = "George"},
new Employee {Code = "E005", Name = "Jason"},
new Employee {Code = "E006", Name = "Robert"},
new Employee {Code = "E007", Name = "Roger"},
new Employee {Code = "E008", Name = "Patrick"},
new Employee {Code = "E009", Name = "Preston"},
new Employee {Code = "E010", Name = "Theodor"},
new Employee {Code = "E011", Name = "Thomas"},
new Employee {Code = "E012", Name = "Trenton"},
new Employee {Code = "E013", Name = "Abel"},
new Employee {Code = "E014", Name = "Cedrick"},
new Employee {Code = "E015", Name = "Celine"},
new Employee {Code = "E016", Name = "David"},
new Employee {Code = "E017", Name = "Donald"},
new Employee {Code = "E018", Name = "Everett"},
new Employee {Code = "E019", Name = "Fred"},
new Employee {Code = "E020", Name = "Harold"},
new Employee {Code = "E021", Name = "Khalid"},
new Employee {Code = "E022", Name = "Lionel"},
new Employee {Code = "E023", Name = "Manuel"}
};
public MainWindow()
{
InitializeComponent();
dataGridEmp.ItemsSource = EmpCollection;
}
private void OnDataGridCellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
DataGridRow currentRow = e.Row;
int currentRow_index = ((DataGrid)sender).ItemContainerGenerator.IndexFromContainer(currentRow);
if (currentRow.Item as Employee == null) return;
string searchedText = (e.EditingElement as TextBox).Text;
for (int i = 0; i < dataGridEmp.Items.Count; i++)
{
if (i == currentRow_index) continue;
dataGridEmp.ScrollIntoView(dataGridEmp.Items[i]);
DataGridRow row = (DataGridRow)dataGridEmp.ItemContainerGenerator.ContainerFromIndex(i);
if (row.Item as Employee == null) break;
string cellContent = (row.Item as Employee).Name;
if (cellContent != null && cellContent.Equals(searchedText))
{
object item = dataGridEmp.Items[i];
dataGridEmp.SelectedItem = item;
dataGridEmp.ScrollIntoView(item);
row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
break;
}
}
}
}
我要防止输入重复的名称。当我输入新名称时,一切都按预期进行。但是,当我在数据网格中输入一个名称时,就会发生一些奇怪的事情:如果在视图中已经存在现有名称,则根据需要选择正确的行,但是如果不在视图中,则选择下一行。尝试输入第一个“ Fred”和下一个“ George”。
当我进行调试时,还会看到另一个非常令人困惑的事情(我无法粘贴图像,因此我将进行描述)。在行上设置断点
row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
,然后输入一个重复的名称(“乔治”)。调试器在那里停止,但是如果您尝试使用F10,它就不会进入“中断”状态。 (下一行),但停留在断点上。仅在第二个F10上,它才继续执行“ break;”。很奇怪!
很明显,插入行将使信息在视图中向上移动,而选择将移至下一行。但是为什么以及如何避免呢?接下来,当输入重复的名称时,如何删除附加的行,然后将焦点移至现有名称?