C# 获取位于DataGrid中DataGridTemplateColumn内的文本框的文本
我有一个带有一些列的数据网格。其中之一是模板列。该TemplateColumn的声明如下所示:C# 获取位于DataGrid中DataGridTemplateColumn内的文本框的文本,c#,wpf,datagrid,C#,Wpf,Datagrid,我有一个带有一些列的数据网格。其中之一是模板列。该TemplateColumn的声明如下所示: <DataGridTemplateColumn Header="First Name"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding FirstName}" /> </Da
<DataGridTemplateColumn Header="First Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding FirstName}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding FirstName}" Loaded="TextBox_Loaded_1"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
上述代码返回ContentPresenter而不是TextBlock。为什么会发生这种情况
此外,ContentPresenter的内容为空。在绑定中,您可以使用
UpdateSourceTrigger=PropertyChanged
,以便在DataGrid\u PreviewKeyDown
中不会发现FirstName属性为空
<DataGridTemplateColumn Header="First Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding FirstName}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding FirstName, UpdateSourceTrigger=PropertyChanged}" Loaded="TextBox_Loaded_1"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
var cell = e.OriginalSource as DataGridCell;
if (cell != null)
{
var dataitem = cell.DataContext; //Here you can you AS keyword to convert the DataContext to your item type.
//dataitem.FirstName
}
}
}
一些评论指出,在这里访问
ViewModel
可能是一种选择,虽然在某些情况下这是一种更简单的方法,但它不处理非数据绑定字段,而且很可能不太通用
我们要做的是找到在单击的DataGridCell
的VisualTree
上行走的第一个TextBlock
子对象。考虑以下样本:
<DataGrid Name="Test" PreviewKeyDown="DataGrid_PreviewKeyDown">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="Bla Bla 123" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
有关如何搜索儿童的更多信息和理解,请查看,解释WPF中视觉树和逻辑树之间的区别。我已经解决了我的问题。我从e.OriginalSource获得了当前正在编辑的文本框。您已经绑定到FirstName,所以为什么不访问DataContext并使用FirstName属性?@d.moncada由于停电,很抱歉回复太晚。只要我在单元格中输入一些数据并按enter键,我就需要它的值。当时FirstName属性是空的,所以我不能使用它。@Sajeetharan很抱歉回复得太晚,因为停电了。我已经浏览了你建议的那一页。回答者使用了FindChild方法,该方法需要name参数,但我正在开发类似于可重用控件的东西,因此将使用此控件的开发人员可能不会提供名称,或者我可能无法猜出控件的名称。因此,我需要一种通用的方法。同样,在我在问题中提供的上述代码中,这一行给了我ContentPresenter而不是Textblock:
var CellTemplate=((DataGridCell)dep).Content
你能帮我一下你是怎么做到的吗?@C.jacking这是很久以前的事了,但我想你可以检查e.OriginalSource的值。在那里你会得到一些属性,你的文本框的文本是可用的。我正在使用Textblock,这样行吗?我面临着完全相同的挑战problem@C.jacking是的,你可以试试。但我离开WPF还不到两年,所以我不记得了。
<DataGrid Name="Test" PreviewKeyDown="DataGrid_PreviewKeyDown">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="Bla Bla 123" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
var pressedCell = e.OriginalSource as DataGridCell;
if (pressedCell != null)
{
var textBlock = FindVisualChild<TextBlock>(pressedCell);
if (textBlock != null)
{
MessageBox.Show("Text: " + textBlock.Text);
//or more useful stuff
}
}
}
}
private static T FindVisualChild<T>(DependencyObject item)
where T : DependencyObject
{
var childCount = VisualTreeHelper.GetChildrenCount(item);
var result = item as T;
//the for-loop contains a null check; we stop when we find the result.
//so the stop condition for this method is embedded in the initialization
//of the result variable.
for (int i = 0; i < childCount && result == null; i++)
{
result = FindVisualChild<T>(VisualTreeHelper.GetChild(item, i));
}
return result;
}