1

私が何をしても、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 が含まれていないことはわかっていますが、バインドする要素とパスを指定しているときに、これが問題の原因になるとは思いません。何か案は?

4

1 に答える 1

2

これを機能させる唯一の方法は、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>

これが同じ問題を抱えている人に役立つことを願っています...お楽しみください!

于 2010-02-26T00:39:35.470 に答える