2015-02-13 1 views
0

DI'm пытается выставить свойство DataGrid.Columns для UserControl-предшественника, как я сделал с источником элементов, используя answer here. Там doens't, кажется, какие свойства доступны для меня, чтобы связать DataColumns следующим образом:Bind DataGrid.Columns collection to ancestor в пользовательском WPF UserControl

<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)); 
    } 
} 

Edit: Чтобы уточнить, я пытаюсь указать столбцы пользовательского элемента управления и связать DataGrid с теми.

+0

Вы пытаетесь указать столбцы для пользовательского элемента управления и bi и DataGrid к этим? Или вы пытаетесь сделать пользовательский контроль осведомленным о столбцах, которые имеет DataGrid? – NextInLine

+0

Я пытаюсь указать столбцы в пользовательском элементе управления и привязать DataGrid к этим. –

ответ

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 и предотвратить утечку памяти (это будет проблемой, когда срок службы вашего пользовательского элемента больше, чем срок службы вашей сетки данных, или если ваша сетка данных была всегда выгружена и перезагружена в визуальное дерево)