2010-02-24 47 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

相关问题