是否可以在DataGridTemplateColumn属性中使用Binding

时间:2010-02-24 18:33:28

标签: silverlight binding datagridtemplatecolumn

似乎无论我做什么,在尝试绑定silverlight中DataGridTemplateColumn中的属性时,我得到AG_E_PARSER_PROPERTY_NOT_FOUND。我甚至试过尝试以下

            <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,但是当我给它提供绑定的元素和路径时,我不觉得这应该是问题的原因。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

事实证明,实现它的唯一方法就是像DataGridBoundColumn一样实现它。想法是绑定绑定属性。此属性将在内部将绑定设置为私有DependencyProperty。当该属性更改时,您可以执行DependencyProperty Change Callback中所需的任何操作。

以下是一个例子:

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

希望这可以帮助任何有同样问题的人...享受!