Pages

Sunday, 12 December 2010

How to pass an ObservableCollection of DataGridColumns to a DataGrid placed in a UserControl

We have a UserControl with a DataGrid and we want to expose Columns property to make it accessible in XAML. To make a property visible in XAML we have to define a DependencyProperty but it is not everything apart from that we have to take care about DependencyProperty collection changes and refresh DataGrid Columns accordingly.

Example:

   1:  <Window x:Class="Test.MainWindow"
   2:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:          xmlns:local="clr-namespace:Test"
   5:          Title="MainWindow" Height="350" Width="525">
   6:      <StackPanel x:Name="s">
   7:          <local:UserControl1 x:Name="uc1">
   8:              <local:UserControl1.Columns>
   9:                  <DataGridTextColumn Header="001"/>
  10:                  <DataGridTextColumn Header="002"/>
  11:                  <DataGridTextColumn Header="003"/>
  12:                  <DataGridTextColumn Header="004"/>
  13:              </local:UserControl1.Columns>
  14:          </local:UserControl1>
  15:          <local:UserControl1>
  16:              <local:UserControl1.Columns>
  17:                  <DataGridTextColumn Header="001"/>
  18:                  <DataGridTextColumn Header="002"/>
  19:              </local:UserControl1.Columns>
  20:          </local:UserControl1>
  21:          <Button Click="HandleButtonClick" Content="UpdateHeaders"/>
  22:      </StackPanel>
  23:  </Window>

   1:  namespace Test
   2:  {
   3:      public partial class MainWindow : Window
   4:      {
   5:          public MainWindow()
   6:          {
   7:              InitializeComponent();
   8:          }
   9:   
  10:          private void HandleButtonClick(object sender, RoutedEventArgs e)
  11:          {
  12:              var collection = new ObservableCollection<DataGridColumn>();
  13:              uc1.Columns = collection;
  14:              collection.Add(new DataGridTextColumn() { Header = "111" });
  15:              collection.Add(new DataGridTextColumn() { Header = "222" });
  16:              collection.Add(new DataGridTextColumn() { Header = "333" });
  17:          }
  18:   
  19:      }
  20:  }

   1:  <UserControl x:Class="Test.UserControl1"
   2:               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:               xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
   5:               xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
   6:               mc:Ignorable="d" 
   7:               d:DesignHeight="300" d:DesignWidth="300">
   8:      <DataGrid x:Name="dg">
   9:   
  10:      </DataGrid>
  11:  </UserControl>


   1:  namespace Test
   2:  {
   3:      public partial class UserControl1 : UserControl
   4:      {
   5:          public static DependencyProperty ColumnsProperty = DependencyProperty.Register("Columns", 
   6:              typeof(ObservableCollection<DataGridColumn>), typeof(UserControl1), new FrameworkPropertyMetadata(Handle));
   7:   
   8:          public UserControl1()
   9:          {
  10:              InitializeComponent();
  11:              Columns = new ObservableCollection<DataGridColumn>();
  12:          }
  13:   
  14:          void HandleCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
  15:          {
  16:              if (e.NewItems != null)
  17:                  foreach (var column in e.NewItems)
  18:                      dg.Columns.Add(column as DataGridColumn);
  19:              if (e.OldItems != null)
  20:                  foreach (var column in e.OldItems)
  21:                      dg.Columns.Remove(column as DataGridColumn);
  22:          }
  23:   
  24:          public ObservableCollection<DataGridColumn> Columns
  25:          {
  26:              get { return (ObservableCollection<DataGridColumn>)GetValue(UserControl1.ColumnsProperty); }
  27:              set { SetValue(UserControl1.ColumnsProperty, value); }
  28:          }
  29:   
  30:          private static void Handle(DependencyObject d, DependencyPropertyChangedEventArgs e)
  31:          {
  32:              var uc = d as UserControl1;
  33:              if (e.OldValue != null)
  34:              {
  35:                  uc.dg.Columns.Clear();
  36:                  uc.RemoveCollectionChangedHandler(e.OldValue as ObservableCollection<DataGridColumn>);
  37:              }
  38:              if (e.NewValue != null)
  39:              {
  40:                  uc.AddCollectionChangedHandler(e.NewValue as ObservableCollection<DataGridColumn>);
  41:              }
  42:          }
  43:   
  44:          private void AddCollectionChangedHandler(ObservableCollection<DataGridColumn> columns)
  45:          {
  46:              columns.CollectionChanged += HandleCollectionChanged;
  47:              foreach (var column in columns)
  48:                  dg.Columns.Add(column);
  49:          }
  50:   
  51:          private void RemoveCollectionChangedHandler(ObservableCollection<DataGridColumn> columns)
  52:          {
  53:              columns.CollectionChanged -= HandleCollectionChanged;
  54:          }
  55:      }
  56:  }

No comments:

Post a Comment