将DataGrid.Columns集合绑定到自定义WPF UserControl中的祖先

时间:2015-02-13 18:02:19

标签: c# wpf xaml datagrid user-controls

DI尝试将DataGrid.Columns属性公开给Ancestor UserControl,就像我使用answer here对项目来源一样。似乎有任何属性可供我以下列方式绑定DataColumns:

<PagedDataGrid>
    <PagedDataGrid.Columns>
        <DataGridTextColumn Header="Custom Column"/>
    <PagedDataGrid.Columns>
</PagedDataGrid>

这是我到目前为止所拥有的。我是否需要以某种方式在代码中执行此操作?

XAML:

<UserControl x:Class="WpfPagedGrid.PagedDataGrid"
         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" 
         xmlns:local="clr-namespace:WpfPagedGrid" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <WrapPanel><TextBlock>Paging Controls...</TextBlock></WrapPanel>
        <DataGrid Name="dataGrid" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
                                AncestorType=local:PagedDataGrid, AncestorLevel=1}, Path=ItemsSource}">
        </DataGrid>
    </Grid>
</UserControl>

C#:

namespace WpfPagedGrid {
    public partial class PagedDataGrid : UserControl {
        public PagedDataGrid() { InitializeComponent(); }

        public IEnumerable ItemsSource {
            get { return (IEnumerable)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }

        public static readonly DependencyProperty ItemsSourceProperty = DataGrid.ItemsSourceProperty.AddOwner(typeof(PagedDataGrid));

        //Does not work as there is no DataGrid.Columns property...
        //public ObservableCollection<DataGridColumn> Columns {
            //get { return (ObservableCollection<DataGridColumn>)GetValue(ColumnsProperty); }
            //set { SetValue(ItemsSourceProperty, value); }
        //}

        //public static readonly DependencyProperty ColumnsProperty = DataGrid.CloumnsProperty.AddOwner(typeof(PagedDataGrid));
    }
}

编辑: 为了澄清,我试图在用户控件上指定列并将DataGrid绑定到那些。

1 个答案:

答案 0 :(得分:2)

由于DataGrid.Columns是只读集合,因此无法直接绑定。相反,您可以通过通常称为附加行为的方式获得此信息。基本上是:

  • 创建一个附加属性为ObservableCollection
  • 的类
  • 将此类绑定到UserControl上的集合,并将其附加到DataGrid
  • 在附加属性的On[Property]Changed处理程序中,您的发件人将是DataGrid实例,并且传入的集合将是您的列。然后,您可以设置DataGrid列。

所以在代码中:

<DataGrid Name="dataGrid" ...
    MyColumnHelper.Columns="{Binding RelativeSource={RelativeSource FindAncestor,
    AncestorType=local:PagedDataGrid, AncestorLevel=1}, Path=MyColumns}" />

对于处理程序:

OnMyColumnHelperColumnsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
    DataGrid.Columns.Clear();
    foreach(var column in (IEnumerable)args.NewValue)
    {
        DataGrid.Columns.Add(column);
    }
}

警告 - 上面的代码是为用户控件上的基础集合每次要添加或删除列时创建新集合的内容编写的。虽然您可以使用ObservableCollection,但您会遇到复杂问题:

  • 您必须在上面的事件处理程序中订阅其CollectionChanged事件
  • 然后您必须使用弱事件或订阅DataGrid.Unloaded事件,以便您可以取消订阅CollectionChanged并防止内存泄漏(这将是您的用户的生命周期中的问题控制比数据网格的控制长,或者数据网格被卸载并重新加载到可视化树中)