I have a textbox inside a datagrid header.
I am trying to get its content when clicking on a totally unrelated button elsewhere in the page (cannot use selectedItem).
Was able to implement it using the below code.
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;
}
By using this above method I am able to get the Textbox 'txtName' from the Template. But I am afraid with more columns and more data the search might get heavy.
I tried to find the row which contains the header so that search can be run only on the row but it was not successful.
Is there any better and efficient way to do the same?
If all you need is to get the TextBox
's text, you could databind the TextBox
:
<TextBox Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type local:MyWindow}},
Path=TheTextBoxValue}"/>
This example assumes that the grid has an ancestor called MyWindow
in the XAML local
namespace, and that this window has a string valued property called TheTextBoxValue
.
Then, you always have access to the TextBox
´s value and you do not need to search the logical tree of the DataGrid
.