【问题标题】:Bind DataGrid.Columns collection to ancestor in custom WPF UserControl将 DataGrid.Columns 集合绑定到自定义 WPF UserControl 中的祖先
【发布时间】:2015-04-14 20:43:02
【问题描述】:

DI 正在尝试将 DataGrid.Columns 属性公开给 Ancestor UserControl,就像我使用 answer here 对项目源所做的那样。似乎没有任何属性可供我按以下方式绑定 DataColumn:

<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 绑定到这些列。

【问题讨论】:

  • 您是否尝试在用户控件上指定列并将 DataGrid 绑定到这些列?或者你想让用户控件知道 DataGrid 有哪些列?
  • 我正在尝试在用户控件上指定列并将 DataGrid 绑定到这些列。

标签: c# wpf xaml datagrid user-controls


【解决方案1】:

由于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 并防止内存泄漏(这将是您的用户控件的生命周期长于您的数据网格,或者如果您的数据网格曾经被卸载并重新加载到可视化树中)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    • 2013-01-20
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多