【问题标题】:Is it possible to use Binding in a DataGridTemplateColumn property是否可以在 DataGridTemplateColumn 属性中使用绑定
【发布时间】:2010-02-24 18:33:27
【问题描述】:

似乎无论我做什么,在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,但是当我为其提供要绑定的元素和路径时,我不认为这应该是问题的原因。有什么想法吗?

【问题讨论】:

    标签: silverlight binding datagridtemplatecolumn


    【解决方案1】:

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

    这是一个例子:

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

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

    【讨论】:

    • 我尝试了上面的代码,但我得到“目标不是 FrameworkElement 或 CollectionViewSource 类型。”异常...关于调用 BindingOperations.SetBinding(this,..) 时的可见性绑定,有什么想法吗?
    • FWIW,我使用此代码作为起点来构建具有动态列的数据网格。感谢您的发帖,如果有人想查看遵循此模式的另一个示例,请参阅我的博客文章:pettijohn.com/2011/01/silverlight-datagrid-with-dynamic.html
    猜你喜欢
    • 2011-12-18
    • 1970-01-01
    • 2013-01-30
    • 2010-10-27
    • 2020-03-15
    • 2011-03-21
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    相关资源
    最近更新 更多