【问题标题】:Display user control in DatagridViewCell在 DatagridViewCell 中显示用户控件
【发布时间】:2012-06-06 19:07:54
【问题描述】:

Winforms .NET 3.5 (C#)

我有一个 DataGridView (DGView),并创建了要在 DGView 中显示的 CustomColumn 和 CustomCell。我创建了一个我想在 CustomCell 中显示的 CustomUserControl。

问题:我在列中看不到用户控件。我想我需要在 CustomCell 中覆盖 Paint() 方法 - 我该怎么做?

注意 - 托管用户控件的 MSDN 示例用于编辑单元格值 - 您可以在其中使您的用户控件在您正在编辑单元格的位置可见。我希望我的用户控件呈现为普通的 winform 控件。此用户控件显示行的通知 .. 并且每行可以有不同的通知。我希望用户能够单击通知并获取有关它的更多详细信息。 ..但现在我被困在“如何显示这个用户控件”

任何指针都将受到高度赞赏。

 public class CustomColumn : DataGridViewColumn {
    public CustomColumn() : base(new CustomeCell()) { }
    public override DataGridViewCell CellTemplate
    {
        get
        {
            return base.CellTemplate;
        }
        set
        {
            // Ensure that the cell used for the template is a CalendarCell.
            if (value != null &&
                !value.GetType().IsAssignableFrom(typeof(CustomeCell)))
            {
                throw new InvalidCastException("It should be a custom Cell");
            }
            base.CellTemplate = value;
        }
    }
}
public class CustomeCell : DataGridViewTextBoxCell
{
    public CustomeCell() : base() { }
    public override Type ValueType
    {
        get
        {
            return typeof(CustomUserControl);
        }
    }
    public override Type FormattedValueType
    {
        get
        {
            return typeof(CustomUserControl);
        }
    }
}

【问题讨论】:

  • 您还必须定义一个从 Control 派生并实现 IDataGridViewEditingControl 接口的类。
  • @AngshumanAgarwal 正如我在问题中提到的 - 我不想编辑,我只想在一列中显示所有行的用户控件。
  • 我不太明白..但是您想向用户显示 datagridview 的未显示单元格的值?? (即当用户在单元格上单击一次时)如果是这样,那么只需将 ToolTip 与 SQLQuery 或 LINQ 一起使用

标签: c# winforms


【解决方案1】:

第一次尝试:我尝试在需要的网格上放置一个用户控件。问题:滚动数据网格视图需要重新排列所有这些用户控件。 结果 - 被拒绝。

第二次尝试:我构建了一个用户控件并将其绘制在适当的单元格中。 结果 - 目前有效。

我只是在CustomCell 类中覆盖了DataGridViewCellPaintOnClick 方法。

public class CustomeCell : DataGridViewCell
{
    public override Type ValueType
    {
        get { return typeof(CustomUserControl); } 
    }

    protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
    {
        var ctrl = (CustomUserControl) value;
        var img = new Bitmap(cellBounds.Width, cellBounds.Height);
        ctrl.DrawToBitmap(img, new Rectangle(0, 0, ctrl.Width, ctrl.Height));
        graphics.DrawImage(img, cellBounds.Location);
    }

    protected override void OnClick(DataGridViewCellEventArgs e)
    {
        List<InfoObject> objs = DataGridView.DataSource as List<InfoObject>;
        if (objs == null)
            return;
        if (e.RowIndex < 0 || e.RowIndex >= objs.Count)
            return;

        CustomUserControl ctrl = objs[e.RowIndex].Ctrl;
        // Take any action - I will just change the color for now.
        ctrl.BackColor = Color.Red;
        ctrl.Refresh();
        DataGridView.InvalidateCell(e.ColumnIndex, e.RowIndex);
    }
}

该示例在CustomCellCustomColumn 中呈现CustomControl ;)。当用户点击单元格时,CustomCellOnClick 处理点击。理想情况下,我想将该点击委托给自定义用户控件CustomControl - 它应该像点击自身一样处理事件(自定义用户控件可以在内部托管多个控件) - 所以它在那里并不复杂。

public class CustomColumn : DataGridViewColumn
{
    public CustomColumn() : base(new CustomeCell()) { }

    public override DataGridViewCell CellTemplate
    {
        get { return base.CellTemplate; }
        set
        {
            if (value != null && !value.GetType()
                .IsAssignableFrom(typeof (CustomeCell)))
                throw new InvalidCastException("It should be a custom Cell");
            base.CellTemplate = value;
        }
    }
}

【讨论】:

  • 我将此解决方案与享元模式相结合。太棒了 - 效果很好。
【解决方案2】:

DataGridView 控件仅支持在单元格处于编辑模式时显示实际控件。 DataGridView 控件并非旨在显示多个控件或每行重复一组控件。 DataGridView 控件在未编辑单元格时绘制控件的表示形式。该表示可以根据需要进行详细说明。例如,无论单元格是否处于编辑状态,DataGridViewButtonCell 都会绘制一个按钮。

但是,您可以通过 DataGridView.Controls.Add() 方法添加控件,并设置它们的位置和大小以使它们托管在单元格中,but showing controls in all cells regardless of editing make no sense.

阅读here

[更新 - 来自 MS DataGridView 团队的 Prog Mgr]

http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/394e04a8-d918-4fdd-be03-dfa13f6a1e66?persist=True

【讨论】:

  • MS 不支持某些不同的东西 - 但我不同意“但无论编辑如何在所有单元格中显示控件都是没有意义的。” - 考虑您正在查看客户订单列表 - 每个订单可以有不同的通知(无库存、不完整的地址、重复订单、延期交货 .. 等)我希望我的用户“查看”这些通知 - 最好在名为通知! - 无法编辑它们! - 但如果他们点击其中之一,就能看到更多细节。
  • 有趣!您可以阅读 DataGridView 程序经理的 cmets。我用 msdn 链接更新了答案。
  • 我不同意“但无论编辑如何在所有单元格中显示控件都是没有意义的。”我刚刚发现了这个问题,因为我想在单元格中放置一个自定义按钮来对选定的行执行一些操作。如果这对您没有意义,为什么会有 DataGridViewButtonCell ?
猜你喜欢
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多