2013-09-30 1 views
0

Я пытаюсь подклассифицировать DataGridBoundColumn, чтобы создать тот, который отображает ComboBox. API зеркала в ComboBox в:Подкласс DataGridBoundColumn в Silverlight

<sdk:DataGrid x:Name="dataGrid1" 
       AutoGenerateColumns="False" 
       ItemsSource="{Binding Items}"> 
    <sdk:DataGrid.Columns> 
     <controls:DataGridComboBoxColumn 
      Binding="{Binding SalutationId}" 
      SelectedValuePath="SalutationId" 
      DisplayMemberPath="SalutationName" 
      ItemsSource="{Binding Salutations, ElementName=UserControl}" 
      Header="Salutation" 
      /> 
    </sdk:DataGrid.Columns> 
</sdk:DataGrid> 

Необъяснимо, связывание ItemsSource с помощью XAML не работает, но делает это программно делает - т.е.

private void BindSalutations() 
    { 
     SalutationColumn = (DataGridComboBoxColumn) this.dataGrid1.Columns[1]; 
     BindingOperations.SetBinding(
      SalutationColumn, 
      DataGridComboBoxColumn.ItemsSourceProperty, 
      new Binding("Salutations") { Source = this }); 
    } 

Я удостоверился ItemsSource определяется как DependencyProperty, но безрезультатно. Вот моя реализация:

using System; 
using System.Collections; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Ink; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 

namespace SlDataGridColumn.Controls 
{ 
    public class DataGridComboBoxColumn: DataGridBoundColumn 
    { 
     public DataGridComboBoxColumn() 
      : base() 
     { 

     } 

     #region ItemsSource Dependency Property 
#if false 
     private IEnumerable _itemsSource; 

     public IEnumerable ItemsSource 
     { 
      get { return _itemsSource; } 
      set { _itemsSource = value; base.NotifyPropertyChanged("ItemsSource"); } 
     } 

#else 
     /// <summary> 
     /// Get or Sets the ItemsSource dependency property. 
     /// </summary> 
     public IEnumerable ItemsSource 
     { 
      get { return (IEnumerable)GetValue(ItemsSourceProperty); } 
      set { SetValue(ItemsSourceProperty, value); base.NotifyPropertyChanged("ItemsSource"); } 
     } 

     /// <summary> 
     /// Identifies the ItemsSource dependency property. This enables animation, styling, binding, etc... 
     /// </summary> 
     public static readonly DependencyProperty ItemsSourceProperty = 
      DependencyProperty.Register("ItemsSource", 
             typeof(IEnumerable), 
             typeof(DataGridComboBoxColumn), 
             new PropertyMetadata(null, OnItemsSourcePropertyChanged)); 

     /// <summary> 
     /// ItemsSource changed handler. 
     /// </summary> 
     /// <param name="d">DataGridComboBoxColumn that changed its ItemsSource.</param> 
     /// <param name="e">DependencyPropertyChangedEventArgs.</param> 
     private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var source = d as DataGridComboBoxColumn; 
      if (source != null) 
      { 
       var value = (IEnumerable)e.NewValue; 
       source.NotifyPropertyChanged("ItemsSource"); 
      } 
     } 
#endif 
     #endregion ItemsSource Dependency Property 

     #region SelectedValuePath Dependency Property 

     /// <summary> 
     /// Get or Sets the SelectedValuePath dependency property. 
     /// </summary> 
     public string SelectedValuePath 
     { 
      get { return (string)GetValue(SelectedValuePathProperty); } 
      set { SetValue(SelectedValuePathProperty, value); } 
     } 

     /// <summary> 
     /// Identifies the SelectedValuePath dependency property. This enables animation, styling, binding, etc... 
     /// </summary> 
     public static readonly DependencyProperty SelectedValuePathProperty = 
      DependencyProperty.Register("SelectedValuePath", 
             typeof(string), 
             typeof(DataGridComboBoxColumn), 
             new PropertyMetadata("", OnSelectedValuePathPropertyChanged)); 

     /// <summary> 
     /// SelectedValuePath changed handler. 
     /// </summary> 
     /// <param name="d">DataGridComboBoxColumn that changed its SelectedValuePath.</param> 
     /// <param name="e">DependencyPropertyChangedEventArgs.</param> 
     private static void OnSelectedValuePathPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var source = d as DataGridComboBoxColumn; 
      if (source != null) 
      { 
       var value = (string)e.NewValue; 
       source.NotifyPropertyChanged("SelectedValuePath"); 
      } 
     } 

     #endregion SelectedValuePath Dependency Property 

     #region DisplayMemberPath Dependency Property 

     /// <summary> 
     /// Get or Sets the DisplayMemberPath dependency property. 
     /// </summary> 
     public string DisplayMemberPath 
     { 
      get { return (string)GetValue(DisplayMemberPathProperty); } 
      set { SetValue(DisplayMemberPathProperty, value); } 
     } 

     /// <summary> 
     /// Identifies the DisplayMemberPath dependency property. This enables animation, styling, binding, etc... 
     /// </summary> 
     public static readonly DependencyProperty DisplayMemberPathProperty = 
      DependencyProperty.Register("DisplayMemberPath", 
             typeof(string), 
             typeof(DataGridComboBoxColumn), 
             new PropertyMetadata("", OnDisplayMemberPathPropertyChanged)); 

     /// <summary> 
     /// DisplayMemberPath changed handler. 
     /// </summary> 
     /// <param name="d">DataGridComboBoxColumn that changed its DisplayMemberPath.</param> 
     /// <param name="e">DependencyPropertyChangedEventArgs.</param> 
     private static void OnDisplayMemberPathPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var source = d as DataGridComboBoxColumn; 
      if (source != null) 
      { 
       var value = (string)e.NewValue; 
       source.NotifyPropertyChanged("DisplayMemberPath"); 
      } 
     } 

     #endregion DisplayMemberPath Dependency Property 

     protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) 
     { 
      var cb = new ComboBox(); 
      BindingOperations.SetBinding(cb, ComboBox.SelectedValueProperty, new Binding(this.Binding) { Source = dataItem }); 
      BindingOperations.SetBinding(cb, ComboBox.ItemsSourceProperty, new Binding("ItemsSource") { Source = this }); 
      BindingOperations.SetBinding(cb, ComboBox.DisplayMemberPathProperty, new Binding("DisplayMemberPath") { Source = this }); 
      BindingOperations.SetBinding(cb, ComboBox.SelectedValuePathProperty, new Binding("SelectedValuePath") { Source = this }); 
      return cb; 
     } 

     protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) 
     { 
      var cb = new ComboBox(); 
      cb.DataContext = dataItem; 
      BindingOperations.SetBinding(cb, ComboBox.ItemsSourceProperty, new Binding("ItemsSource") { Source = this }); 
      BindingOperations.SetBinding(cb, ComboBox.DisplayMemberPathProperty, new Binding("DisplayMemberPath") { Source = this }); 
      BindingOperations.SetBinding(cb, ComboBox.SelectedValuePathProperty, new Binding("SelectedValuePath") { Source = this }); 
      BindingOperations.SetBinding(cb, ComboBox.SelectedValueProperty, new Binding(this.Binding.Path.Path)); 
      return cb; 
     } 

     protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs args) 
     { 
      return args.OriginalSource; 
     } 
    } 
} 

Пример исходного кода проекта является here

+0

Если все работает, почему вы разместили здесь? в чем проблема? – Sajeetharan

+0

привязка XAML не делает. –

ответ

0

DataGridColumn является DependencyObject и не FrameworkElement. Это различие важно для понимания проблемы. См. here и here.

Следующая привязка не работает, потому что DependencyObject не может связываться через ElementName.

<controls:DataGridComboBoxColumn 
     ItemsSource="{Binding Salutations, ElementName=UserControl}" 
     /> 
Смежные вопросы