【问题标题】:WPF DataGrid : TemplateColumn with UserControl and TextBlockWPF DataGrid:带有 UserControl 和 TextBlock 的 TemplateColumn
【发布时间】:2015-08-29 11:32:40
【问题描述】:

我有点卡在这里..搜索了两天,没有找到解决方案。

我想要实现的是 DataGridComboBoxColumn 的行为。 我需要它的DisplayMemberPathSelectedValuePathSelectedValueBinding 属性..

我的 UserControl 类似于 CellEditingTemplate 中的 ComboBox 和CellTemplate中的TextBlock。

我在代码中做所有这些,因为这些列可能不一定存在..

这是我定义 TemplateColumn 的地方:

DataGridTemplateColumn tcol = new DataGridTemplateColumn();
tcol.Header = "accCust";

FrameworkElementFactory texttablF = new FrameworkElementFactory(typeof(TextTableBox));
texttablF.SetValue(TextTableBox.TableSourceProperty, accTable.DefaultView);

FrameworkElementFactory tb = new FrameworkElementFactory(typeof(TextBlock));
texttablF.SetBinding(TextBlock.TextProperty, new Binding("Account"));


tcol.CellTemplate = new DataTemplate(typeof(DataGridCell)) { VisualTree = tb };
tcol.CellEditingTemplate = new DataTemplate(typeof(DataGridCell)) { VisualTree = texttablF };

我有两个问题:

  1. TextBlock 显示DataGrid 表中的ID,我希望它显示DisplayMemberPath 中指定的值,我不知道如何实现。
  2. DependencyProperty TableSource 在通过 FrameworkElement.setValue 完成时不起作用。它在以正常方式完成时起作用, 即

    TextTableBox ttb = new TextTableBox();
    ttb.TableSource = src_table.DefaultView;
    

我希望你清楚我的问题是什么。我真正想要的是用我的 UserControl 替换 DataGridComboColumn 中的 ComboBox。

在此先感谢 :) 如果这是一个糟糕的问题,我很抱歉。我是 WPF 新手,正在上高中。

【问题讨论】:

  • 什么是TextTableBox?
  • 那是我的 UserControl.. :)
  • 最好能得到更多关于它的信息。例如 - 它是从哪里继承的?
  • TextTableBox 是一个与 ComboBox 控件非常相似的控件,只是它的 Popus 显示的是 DataGrid 而不是 StackPanel 中的项目列表。该控件继承自 UserControl 类,而不是 ComboBox :)

标签: wpf datagrid datagridtemplatecolumn


【解决方案1】:

因为我想要 ComboBox 的属性,所以我必须从 DataGridComboBoxColumn 继承。

代码如下:

public class DataGridTCBColumn : DataGridComboBoxColumn
{
    private TableComboBox comboBox;

    public DataGridTCBColumn(bool Editable)
    {
        comboBox = new TableComboBox() { IsEditable = Editable };
    }

    // Requires extra field..
    public string SelectedValuePathX
    {
        get
        {
            return (string)this.GetValue(SelectedValuePathXProperty);
        }
        set
        {

            this.SetValue(SelectedValuePathXProperty, value);

        }
    }
    static FrameworkPropertyMetadata SelectedValuePathXPropertyMeta = new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(SelectedValuePathXPropertyChanged));
    public static readonly DependencyProperty SelectedValuePathXProperty =
DependencyProperty.Register("SelectedValueX", typeof(string), typeof(TableComboBox), SelectedValuePathXPropertyMeta);
    private static void SelectedValuePathXPropertyChanged(DependencyObject dobj, DependencyPropertyChangedEventArgs e)
    {}

    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        if (e.Property == DataGridTCBColumn.ItemsSourceProperty)
        {
            comboBox.ItemsSource = ItemsSource;
        }
        else if (e.Property == DataGridTCBColumn.SelectedValuePathProperty)
        {
            comboBox.SelectedValuePath = SelectedValuePath;
        }
        else if (e.Property == DataGridTCBColumn.DisplayMemberPathProperty)
        {
            comboBox.DisplayMemberPath = DisplayMemberPath;
        }

        base.OnPropertyChanged(e);
    }


    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
    {
        return comboBox;
    }
    protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
    {
        DataGridCell cell = editingEventArgs.Source as DataGridCell;
        if (cell != null && !string.IsNullOrEmpty(this.SelectedValuePathX))
        {
            //For Typed DataSet
            object obj = ((DataRowView)editingElement.DataContext).Row[this.SelectedValuePathX];
            comboBox.SelectedValue = obj;
        }

        comboBox.Focus();
        return comboBox.SelectedItem;
    }
    protected override bool CommitCellEdit(FrameworkElement editingElement)
    {   
        if (!string.IsNullOrEmpty(this.SelectedValuePathX) && comboBox.SelectedValue != null)
        ((DataRowView)editingElement.DataContext).Row[this.SelectedValuePathX] = comboBox.SelectedValue;
        return true;
    }
}

必须创建另一个依赖属性SelectedValuePathX。实际上,它完成了SelectedValueBinding 的工作。然而,Binding 从来没有奏效(尝试通过 ComboBox 的源代码 (Microsoft Reference Source),但效果也很好。

希望对某人有所帮助:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 2017-10-09
    • 1970-01-01
    • 2017-12-18
    • 2019-07-23
    • 2011-08-13
    • 1970-01-01
    • 2011-06-05
    相关资源
    最近更新 更多