2010-02-24 6 views
0

Il semble que peu importe ce que je fais, j'obtiens AG_E_PARSER_PROPERTY_NOT_FOUND lorsque j'essaie de lier une propriété dans DataGridTemplateColumn dans silverlight. J'ai même essayé essayé les suivantesEst-il possible d'utiliser la liaison dans une propriété 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> 

Mais pas de chance ... Je sais que le DataGridTemplateColumn ne contient pas de DataContext, mais je ne me sens pas comme cela devrait être la cause du problème quand je suis en lui donnant l'élément et le chemin pour se lier. Des idées?

Répondre

2

Il s'avère que la seule façon de faire fonctionner cela est de l'implémenter comme DataGridBoundColumn. L'idée est de lier à la propriété de liaison. Cette propriété définira en interne la liaison à un DependencyProperty privé. Lorsque cette propriété change, vous pouvez effectuer tout ce qui est nécessaire dans le rappel de modification DependencyProperty.

Voici un exemple:

/// <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> 

Hope this helps toute personne ayant le même problème ... Amusez-vous!

+0

J'ai essayé le code ci-dessus, mais j'obtiens que "la cible n'est pas de type FrameworkElement ou CollectionViewSource". exception ... sur la visibilité de liaison lorsque BindingOperations.SetBinding (this, ..) est appelé, des idées? – Joshscorp

+0

FWIW, j'ai utilisé ce code comme point de départ pour construire une grille de données avec des colonnes dynamiques. Merci de poster, et si quelqu'un veut voir un autre exemple suivant ce modèle, voici mon article de blog à ce sujet: http://www.pettijohn.com/2011/01/silverlight-datagrid-with-dynamic.html –

Questions connexes