WPF DataGrid - 通过父 UserControl 中的自定义 属性 绑定 DataContext
WPF DataGrid - Bind DataContext through custom property in parent UserControl
我正在编写一个包含三个 DataGrid 的新控件(DG_Top、DG_Center、DG_Bottom)。
尝试为此控件设置数据时没有任何反应。
ContextProperties(见下图)已填充,但数据未显示。
在 UserControl (XGrid) 中,我创建了一些属性来管理 DataBindings:
public static readonly DependencyProperty ItemsSource_TopProperty = DependencyProperty.Register("ItemsSource_Top", typeof(IEnumerable), typeof(XGrid));
public static readonly DependencyProperty ItemsSource_CenterProperty = DependencyProperty.Register("ItemsSource_Center", typeof(IEnumerable), typeof(XGrid));
public static readonly DependencyProperty ItemsSource_BottomProperty = DependencyProperty.Register("ItemsSource_Bottom", typeof(IEnumerable), typeof(XGrid));
public static readonly DependencyProperty DataContext_TopProperty = DependencyProperty.Register("DataContext_Top", typeof(object), typeof(XGrid));
public static readonly DependencyProperty DataContext_CenterProperty = DependencyProperty.Register("DataContext_Center", typeof(object), typeof(XGrid));
public static readonly DependencyProperty DataContext_BottomProperty = DependencyProperty.Register("DataContext_Bottom", typeof(object), typeof(XGrid));
public IEnumerable ItemsSource_Top
{
get { return (IEnumerable)GetValue(ItemsSource_TopProperty); }
set
{
SetValue(ItemsSource_TopProperty, value);
OnPropertyChanged();
}
}
public IEnumerable ItemsSource_Center...
public IEnumerable ItemsSource_Bottom...
public object DataContext_Top
{
get { return (object)GetValue(DataContext_TopProperty); }
set
{
SetValue(DataContext_TopProperty, value);
OnPropertyChanged();
}
}
public object DataContext_Center...
public object DataContext_Bottom...
XGrid.xaml 中的绑定如下:
<UserControl x:Class="WPF.XGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
x:Name="control">
<StackPanel>
<DataGrid ItemsSource="{Binding ItemsSource_Top, ElementName=control}"
DataContext="{Binding DataContext_Top, ElementName=control}"
...
我按如下方式使用 XGrid 控件(在 xaml 中):
<iw:XGrid x:Name="XG_Test" ItemsSource_Center="{Binding}" />
并且在 .cs 文件中:
DataTable dt = new DataTable();
dt.Columns.Add("TEST");
dt.Rows.Add(new string[] { "" });
XG_Test.DataContext_Center = dt.DefaultView;
谁能告诉我为什么绑定不起作用?
谢谢!
--------编辑 1--------
Visual Studio 输出没有说明错误
好的,我想我知道问题出在哪里了。您的 DataGrid 的 ItemsSource 绑定没有考虑 DataGrid DataContext,而是在 XGrid 控件的 DataContext 中搜索它的值。
你必须确保你使用的是你想要的 DataContext,做这样的事情:
<iw:XGrid x:Name="XG_Test"
ItemsSource_Center="{Binding DataContext_Center.DefaultView,
RelativeSource={RelativeSource Mode=Self}}" />
但这有点违背了你想要达到的目的,我想......
编辑:我找到了另一种方法,可以使您的原始绑定按预期工作。它要求您修改 UserControl 的代码隐藏并从那里创建 ItemsSource 绑定,而不是从 XAML.
我将以 "top" DataGrid 为例。
首先,为 UserControl 中的 DataGrids 命名,并删除 ItemsSource 绑定:
<DataGrid x:Name="DataGrid_Top"
DataContext="{Binding DataContext_Top, ElementName=control}"
... />
然后,为您的 ItemsSource DependencyProperties 声明一个 属性 更改回调:
public static readonly DependencyProperty ItemsSource_TopProperty =
DependencyProperty.Register("ItemsSource_Top", typeof(IEnumerable),
typeof(XGrid), new PropertyMetadata(null, OnItemsSource_TopPropertyChanged));
在该回调中,您将创建绑定,但方式不同于通常...
private static void OnItemsSource_TopPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var control = sender as XGrid;
var binding = BindingOperations.GetBindingBase(control, XGrid.ItemsSource_TopProperty);
DataGrid_Top.SetBinding(DataGrid.ItemsSourceProperty, binding);
}
就是这样...您有点 "copying" 从 DependencyProperty 绑定到 ItemsSource 属性。
然后您可以再次将 XAML 更改为您的原始示例,它应该可以工作。
<iw:XGrid x:Name="XG_Test" ItemsSource_Center="{Binding}" />
我正在编写一个包含三个 DataGrid 的新控件(DG_Top、DG_Center、DG_Bottom)。
尝试为此控件设置数据时没有任何反应。 ContextProperties(见下图)已填充,但数据未显示。
在 UserControl (XGrid) 中,我创建了一些属性来管理 DataBindings:
public static readonly DependencyProperty ItemsSource_TopProperty = DependencyProperty.Register("ItemsSource_Top", typeof(IEnumerable), typeof(XGrid));
public static readonly DependencyProperty ItemsSource_CenterProperty = DependencyProperty.Register("ItemsSource_Center", typeof(IEnumerable), typeof(XGrid));
public static readonly DependencyProperty ItemsSource_BottomProperty = DependencyProperty.Register("ItemsSource_Bottom", typeof(IEnumerable), typeof(XGrid));
public static readonly DependencyProperty DataContext_TopProperty = DependencyProperty.Register("DataContext_Top", typeof(object), typeof(XGrid));
public static readonly DependencyProperty DataContext_CenterProperty = DependencyProperty.Register("DataContext_Center", typeof(object), typeof(XGrid));
public static readonly DependencyProperty DataContext_BottomProperty = DependencyProperty.Register("DataContext_Bottom", typeof(object), typeof(XGrid));
public IEnumerable ItemsSource_Top
{
get { return (IEnumerable)GetValue(ItemsSource_TopProperty); }
set
{
SetValue(ItemsSource_TopProperty, value);
OnPropertyChanged();
}
}
public IEnumerable ItemsSource_Center...
public IEnumerable ItemsSource_Bottom...
public object DataContext_Top
{
get { return (object)GetValue(DataContext_TopProperty); }
set
{
SetValue(DataContext_TopProperty, value);
OnPropertyChanged();
}
}
public object DataContext_Center...
public object DataContext_Bottom...
XGrid.xaml 中的绑定如下:
<UserControl x:Class="WPF.XGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
x:Name="control">
<StackPanel>
<DataGrid ItemsSource="{Binding ItemsSource_Top, ElementName=control}"
DataContext="{Binding DataContext_Top, ElementName=control}"
...
我按如下方式使用 XGrid 控件(在 xaml 中):
<iw:XGrid x:Name="XG_Test" ItemsSource_Center="{Binding}" />
并且在 .cs 文件中:
DataTable dt = new DataTable();
dt.Columns.Add("TEST");
dt.Rows.Add(new string[] { "" });
XG_Test.DataContext_Center = dt.DefaultView;
谁能告诉我为什么绑定不起作用? 谢谢!
--------编辑 1--------
Visual Studio 输出没有说明错误
好的,我想我知道问题出在哪里了。您的 DataGrid 的 ItemsSource 绑定没有考虑 DataGrid DataContext,而是在 XGrid 控件的 DataContext 中搜索它的值。
你必须确保你使用的是你想要的 DataContext,做这样的事情:
<iw:XGrid x:Name="XG_Test"
ItemsSource_Center="{Binding DataContext_Center.DefaultView,
RelativeSource={RelativeSource Mode=Self}}" />
但这有点违背了你想要达到的目的,我想......
编辑:我找到了另一种方法,可以使您的原始绑定按预期工作。它要求您修改 UserControl 的代码隐藏并从那里创建 ItemsSource 绑定,而不是从 XAML.
我将以 "top" DataGrid 为例。
首先,为 UserControl 中的 DataGrids 命名,并删除 ItemsSource 绑定:
<DataGrid x:Name="DataGrid_Top" DataContext="{Binding DataContext_Top, ElementName=control}" ... />
然后,为您的 ItemsSource DependencyProperties 声明一个 属性 更改回调:
public static readonly DependencyProperty ItemsSource_TopProperty = DependencyProperty.Register("ItemsSource_Top", typeof(IEnumerable), typeof(XGrid), new PropertyMetadata(null, OnItemsSource_TopPropertyChanged));
在该回调中,您将创建绑定,但方式不同于通常...
private static void OnItemsSource_TopPropertyChanged(object sender, DependencyPropertyChangedEventArgs e) { var control = sender as XGrid; var binding = BindingOperations.GetBindingBase(control, XGrid.ItemsSource_TopProperty); DataGrid_Top.SetBinding(DataGrid.ItemsSourceProperty, binding); }
就是这样...您有点 "copying" 从 DependencyProperty 绑定到 ItemsSource 属性。
然后您可以再次将 XAML 更改为您的原始示例,它应该可以工作。
<iw:XGrid x:Name="XG_Test" ItemsSource_Center="{Binding}" />