2010-02-24 62 views
0

似乎無論我做什麼,當試圖綁定Silverlight中的DataGridTemplateColumn中的屬性時,我都會得到AG_E_PARSER_PROPERTY_NOT_FOUND。我甚至試過嘗試以下是否有可能在DataGridTemplateColumn屬性中使用綁定

  <data:DataGridTemplateColumn dataBehaviors:DataGridColumnBehaviors.BindableTextOverride="{Binding ElementName=LayoutRoot, 
                               Path=DataContext.ColumnOneName}"> 
       <data:DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <TextBlock Text="{Binding Name}" /> 
        </DataTemplate> 
       </data:DataGridTemplateColumn.CellTemplate> 
       <data:DataGridTemplateColumn.CellEditingTemplate> 
        <DataTemplate> 
         <TextBox Text="{Binding Name, Mode=TwoWay}" /> 
        </DataTemplate> 
       </data:DataGridTemplateColumn.CellEditingTemplate> 
      </data:DataGridTemplateColumn> 

,但沒有運氣...我知道了DataGridTemplateColumn不包含DataContext的,但我不覺得這應該是當我的問題的原因給它綁定的元素和路徑。有任何想法嗎?

回答

2

原來這樣做的唯一方法就是像DataGridBoundColumn一樣實現它。這個想法是綁定到綁定屬性。該屬性將在內部將綁定設置爲私有的DependencyProperty。當該屬性更改時,您可以執行DependencyProperty Change回調中需要的任何內容。

下面是一個例子:

/// <summary> 
/// Represents a System.Windows.Controls.DataGrid column that can bind to a property 
/// in the grid's data source. This class provides bindable properties ending with the suffix Binding. 
/// These properties will affect the properties with the same name without the suffix 
/// </summary> 
public class DataGridBindableTemplateColumn : DataGridBoundColumn 
{ 
    /// <summary> 
    /// Identifies the DataGridBindableTemplateColumn.HeaderValueProperty dependency property 
    /// </summary> 
    internal static readonly DependencyProperty HeaderValueProperty = 
     DependencyProperty.Register("HeaderValue", typeof(object), typeof(DataGridBindableTemplateColumn), 
      new PropertyMetadata(null, OnHeaderValuePropertyChanged)); 

    /// <summary> 
    /// Identifies the DataGridBindableTemplateColumn.VisibilityValueProperty dependency property 
    /// </summary> 
    internal static readonly DependencyProperty VisibilityValueProperty = 
     DependencyProperty.Register("VisibilityValue", typeof(Visibility), typeof(DataGridBindableTemplateColumn), 
      new PropertyMetadata(Visibility.Visible, OnVisibilityPropertyPropertyChanged)); 

    /// <summary> 
    /// The callback the fires when the VisibilityValueProperty value changes 
    /// </summary> 
    /// <param name="d">The DependencyObject from which the property changed</param> 
    /// <param name="e">The DependencyPropertyChangedEventArgs containing the old and new value for the depenendency property that changed.</param> 
    private static void OnVisibilityPropertyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     DataGridBindableTemplateColumn sender = d as DataGridBindableTemplateColumn; 

     if (sender != null) 
     { 
      sender.OnVisibilityPropertyChanged((Visibility)e.OldValue, (Visibility)e.NewValue); 
     } 
    } 

    /// <summary> 
    /// The callback the fires when the HeaderValueProperty value changes 
    /// </summary> 
    /// <param name="d">The DependencyObject from which the property changed</param> 
    /// <param name="e">The DependencyPropertyChangedEventArgs containing the old and new value for the depenendency property that changed.</param> 
    private static void OnHeaderValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     DataGridBindableTemplateColumn sender = d as DataGridBindableTemplateColumn; 

     if (sender != null) 
     { 
      sender.OnHeaderValueChanged((object)e.OldValue, (object)e.NewValue); 
     } 
    } 

    private Binding _headerBinding; 
    private Binding _visibilityBinding; 

    private DataTemplate _cellEditingTemplate; 
    private DataTemplate _cellTemplate; 

    /// <summary> 
    /// Gets and sets the Binding object used to bind to the Header property 
    /// </summary> 
    public Binding HeaderBinding 
    { 
     get { return _headerBinding; } 
     set 
     { 
      if (_headerBinding != value) 
      {      
       _headerBinding = value; 

       if (_headerBinding != null) 
       {       
        _headerBinding.ValidatesOnExceptions = false; 
        _headerBinding.NotifyOnValidationError = false; 

        BindingOperations.SetBinding(this, HeaderValueProperty, _headerBinding); 
       } 
      } 
     } 
    } 

    /// <summary> 
    /// Gets and sets the Binding object used to bind to the Visibility property 
    /// </summary> 
    public Binding VisibilityBinding 
    { 
     get { return _visibilityBinding; } 
     set 
     { 
      if (_visibilityBinding != value) 
      { 
       _visibilityBinding = value; 

       if (_visibilityBinding != null) 
       { 
        _visibilityBinding.ValidatesOnExceptions = false; 
        _visibilityBinding.NotifyOnValidationError = false; 

        BindingOperations.SetBinding(this, VisibilityValueProperty, _visibilityBinding); 
       } 
      } 
     } 
    } 

    /// <summary> 
    /// Gets or sets the template that is used to display the contents of a cell 
    /// that is in editing mode. 
    /// </summary> 
    public DataTemplate CellEditingTemplate 
    { 
     get { return _cellEditingTemplate; } 
     set 
     { 
      if (_cellEditingTemplate != value) 
      { 
       _cellEditingTemplate = value; 
      } 
     } 
    } 

    /// <summary> 
    /// Gets or sets the template that is used to display the contents of a cell 
    /// that is not in editing mode. 
    /// </summary> 
    public DataTemplate CellTemplate 
    { 
     get { return _cellTemplate; } 
     set 
     { 
      if (_cellTemplate != value) 
      { 
       _cellTemplate = value; 
      } 
     } 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="editingElement"></param> 
    /// <param name="uneditedValue"></param> 
    protected override void CancelCellEdit(FrameworkElement editingElement, object uneditedValue) 
    { 
     editingElement = GenerateEditingElement(null, null); 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="cell"></param> 
    /// <param name="dataItem"></param> 
    /// <returns></returns> 
    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) 
    { 
     if (CellEditingTemplate != null) 
     { 
      return (CellEditingTemplate.LoadContent() as FrameworkElement); 
     } 

     if (CellTemplate != null) 
     { 
      return (CellTemplate.LoadContent() as FrameworkElement); 
     } 

     if (!DesignerProperties.IsInDesignTool) 
     { 
      throw new Exception(string.Format("Missing template for type '{0}'", typeof(DataGridBindableTemplateColumn))); 
     } 

     return null; 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="cell"></param> 
    /// <param name="dataItem"></param> 
    /// <returns></returns> 
    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) 
    { 
     if (CellTemplate != null) 
     { 
      return (CellTemplate.LoadContent() as FrameworkElement); 
     } 

     if (CellEditingTemplate != null) 
     { 
      return (CellEditingTemplate.LoadContent() as FrameworkElement); 
     } 

     if (!DesignerProperties.IsInDesignTool) 
     { 
      throw new Exception(string.Format("Missing template for type '{0}'", typeof(DataGridBindableTemplateColumn))); 
     } 

     return null; 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="editingElement"></param> 
    /// <param name="editingEventArgs"></param> 
    /// <returns></returns> 
    protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs) 
    { 
     return null; 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="oldValue"></param> 
    /// <param name="newValue"></param> 
    protected virtual void OnHeaderValueChanged(object oldValue, object newValue) 
    { 
     Header = newValue; 
    } 

    /// <summary> 
    /// I'm to lazy to write a comment 
    /// </summary> 
    /// <param name="oldValue"></param> 
    /// <param name="newValue"></param> 
    protected virtual void OnVisibilityPropertyChanged(Visibility oldValue, Visibility newValue) 
    { 
     Visibility = newValue; 
    } 
} 

XAML:

<data:DataGridBindableTemplateColumn HeaderBinding="{Binding HeaderOne, Source={StaticResource ViewModel}}" 
             VisibilityBinding="{Binding HeaderOneVisibility, Source={StaticResource ViewMode}}" 
             HeaderStyle="{StaticResource DataColumnStyle}" 
             MinWidth="58"> 
         ... 
    </data:DataGridBindableTemplateColumn> 

希望這有助於任何人以同樣的問題...享受!

+0

我試過上面的代碼,但我得到的「目標不是類型的FrameworkElement或CollectionViewSource」。異常...關於可見性綁定當BindingOperations.SetBinding(this,..)被調用時,有什麼想法? – Joshscorp 2010-03-28 23:48:10

+0

FWIW,我用這段代碼作爲跳轉點來構建一個包含動態列的數據網格。感謝發佈,如果有人想看到這種模式下的另一個例子,這是我的博客文章:http://www.pettijohn.com/2011/01/silverlight-datagrid-with-dynamic.html – 2011-01-20 04:55:56

相關問題