Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取位于DataGrid中DataGridTemplateColumn内的文本框的文本_C#_Wpf_Datagrid - Fatal编程技术网

C# 获取位于DataGrid中DataGridTemplateColumn内的文本框的文本

C# 获取位于DataGrid中DataGridTemplateColumn内的文本框的文本,c#,wpf,datagrid,C#,Wpf,Datagrid,我有一个带有一些列的数据网格。其中之一是模板列。该TemplateColumn的声明如下所示: <DataGridTemplateColumn Header="First Name"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding FirstName}" /> </Da

我有一个带有一些列的数据网格。其中之一是模板列。该TemplateColumn的声明如下所示:

<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;
}