Reputation: 1171
How can I get the binding expression of a DataGrid column in WPF?
This is the XAML for the column:
<DataGridTextColumn x:Name="amountColumn" Header="Amount" Width="100"
Binding="{Binding _Amount, StringFormat=c}"
CellStyle="{StaticResource errorStyle}"/>
Upvotes: 1
Views: 5728
Reputation: 13296
The BindingExpression
objects are on the TextBlock
elements, not on the column. First you need to get a cell. Then your can search for the inner TextBlock
:
var textBlock = cell.FindFirstVisualChild<TextBlock>();
BindingExpression bindingExpression = textBlock.GetBindingExpression(TextBlock.TextProperty);
The code for FindFirstVisualChild()
:
public static class DependencyObjectExtensions
{
public static IEnumerable<T> FindVisualChildren<T>([NotNull] this DependencyObject dependencyObject)
where T : DependencyObject
{
if (dependencyObject == null) throw new ArgumentNullException(nameof(dependencyObject));
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(dependencyObject, i);
if (child is T o)
yield return o;
foreach (T childOfChild in FindVisualChildren<T>(child))
yield return childOfChild;
}
}
public static childItem FindFirstVisualChild<childItem>([NotNull] this DependencyObject dependencyObject)
where childItem : DependencyObject
{
if (dependencyObject == null) throw new ArgumentNullException(nameof(dependencyObject));
return FindVisualChildren<childItem>(dependencyObject).FirstOrDefault();
}
}
Upvotes: 1
Reputation: 126
I use this code to get all binding expressions in a datagrid:
private Collection GetAllBindingsInDatagrid(DataGrid dg)
{
Collection bindings = new Collection();
if (dg.ItemsSource != null) {
foreach (object item in dg.ItemsSource) {
DataGridRow row = dg.ItemContainerGenerator.ContainerFromItem(item);
if (row != null) {
foreach (BindingExpression binding in row.BindingGroup.BindingExpressions) {
bindings.Add(binding);
}
}
}
}
return bindings;
}
EDIT: Since the question was to get the "binding expression" of a column, which refers to a single instance of a binding, I thought the aim was to check if there's any validation errors or something, so the function above iterates the rows. But if the generic "binding" of the column itself is needed (e.g. in order to dynamically add a validation rule) this code could be used:
// first retrieve the Datagrid object as datagrid
DataGridTextColumn column = datagrid.FindName("amountColumn");
Binding binding = column.Binding;
Upvotes: 3
Reputation: 10865
You use BindingExpression
BindingExpression bindingExpression = amountColumn.GetBindingExpression(DataGridTextColumn.BindingProperty);
Upvotes: -2