2013-09-30 2 views
0

DataGridBoundColumn의 하위 클래스를 만들어 ComboBox를 표시하려고합니다. 이 API는 콤보 상자의 거울 :Silverlight의 DataGridBoundColumn 서브 클래스

<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입니다 : 여기 내 구현입니다. 이 구별은 문제를 이해하는 데 중요합니다. herehere을 참조하십시오.

DependencyObject가 ElementName을 통해 바인딩 할 수 없기 때문에 다음 바인딩이 작동하지 않습니다.

<controls:DataGridComboBoxColumn 
     ItemsSource="{Binding Salutations, ElementName=UserControl}" 
     />