从 DataGridTextColumn 中获取一个控件,而无需搜索整个 DataGrid children
Get a control from DataGridTextColumn without searching through the whole DataGrid children
我在数据网格中有一个文本框 header。
我在点击页面其他地方完全不相关的按钮时试图获取其内容(无法使用 selectedItem)。
能够使用以下代码实现它。
XAML :
<DataGrid Name="dataGrid">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" >
<DataGridTextColumn.HeaderTemplate >
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Content, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
<TextBox Name="txtName"/>
</StackPanel>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
C# :
TextBox MyTextbox = FindChild<TextBox>(dataGrid, "txtName");
MessageBox.Show(MyTextbox.Text);
public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
{
if (parent == null)
{
return null;
}
T foundChild = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
T childType = child as T;
if (childType == null)
{
foundChild = FindChild<T>(child, childName);
if (foundChild != null) break;
}
else
if (!string.IsNullOrEmpty(childName))
{
var frameworkElement = child as FrameworkElement;
if (frameworkElement != null && frameworkElement.Name == childName)
{
foundChild = (T)child;
break;
}
else
{
foundChild = FindChild<T>(child, childName);
if (foundChild != null)
{
break;
}
}
}
else
{
foundChild = (T)child;
break;
}
}
return foundChild;
}
通过使用上述方法,我可以从模板中获取文本框 'txtName'。但恐怕随着更多的列和更多的数据,搜索可能会变得繁重。
我试图找到包含 header 的行,以便仅在该行上进行搜索 运行 但没有成功。
有没有更好更有效的方法来做同样的事情?
如果您只需要获取 TextBox
的文本,您可以对 TextBox
:
进行数据绑定
<TextBox Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type local:MyWindow}},
Path=TheTextBoxValue}"/>
此示例假定网格在 XAML local
命名空间中有一个名为 MyWindow
的祖先,并且此 window 有一个值为 属性 称为 TheTextBoxValue
.
然后,您始终可以访问 TextBox
的值,而无需搜索 DataGrid
的逻辑树。
我在数据网格中有一个文本框 header。
我在点击页面其他地方完全不相关的按钮时试图获取其内容(无法使用 selectedItem)。
能够使用以下代码实现它。
XAML :
<DataGrid Name="dataGrid">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" >
<DataGridTextColumn.HeaderTemplate >
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Content, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
<TextBox Name="txtName"/>
</StackPanel>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
C# :
TextBox MyTextbox = FindChild<TextBox>(dataGrid, "txtName");
MessageBox.Show(MyTextbox.Text);
public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
{
if (parent == null)
{
return null;
}
T foundChild = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
T childType = child as T;
if (childType == null)
{
foundChild = FindChild<T>(child, childName);
if (foundChild != null) break;
}
else
if (!string.IsNullOrEmpty(childName))
{
var frameworkElement = child as FrameworkElement;
if (frameworkElement != null && frameworkElement.Name == childName)
{
foundChild = (T)child;
break;
}
else
{
foundChild = FindChild<T>(child, childName);
if (foundChild != null)
{
break;
}
}
}
else
{
foundChild = (T)child;
break;
}
}
return foundChild;
}
通过使用上述方法,我可以从模板中获取文本框 'txtName'。但恐怕随着更多的列和更多的数据,搜索可能会变得繁重。
我试图找到包含 header 的行,以便仅在该行上进行搜索 运行 但没有成功。
有没有更好更有效的方法来做同样的事情?
如果您只需要获取 TextBox
的文本,您可以对 TextBox
:
<TextBox Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type local:MyWindow}},
Path=TheTextBoxValue}"/>
此示例假定网格在 XAML local
命名空间中有一个名为 MyWindow
的祖先,并且此 window 有一个值为 属性 称为 TheTextBoxValue
.
然后,您始终可以访问 TextBox
的值,而无需搜索 DataGrid
的逻辑树。