【问题标题】:How to display different Cells in a Column depending on the type?如何根据类型在列中显示不同的单元格?
【发布时间】:2021-02-02 07:22:28
【问题描述】:

我有一个IItemParameter 类型的接口,并且很少用泛型实例化它。 定义如下:

public interface IItemParameter
{
    string Name { get; set; }
}

public struct ItemParameter<T> : IItemParameter
{
    public string Name { get; set; }
    private T _Default { get; set; }
    public T Default { get => _Default; set => _Default = value; }
}

我实例化 ItemParameter&lt;int&gt;ItemParameter&lt;string&gt;ItemParameter&lt;bool&gt;

我想在包含两列的 DataGridView 中显示这些类型的集合:
NameValue,其中 Name 是 Parameter 的 Name 属性,Value 显示为TextBoxCell (string/int) 或 CheckBoxCell(bool)

我使用BindingList&lt;IItemParameter&gt; 来存储参数,如下所示:

//Transform ObjectParameters into ItemParameters for display
foreach (var param in parameters)
{
    if (param is ObjectParameter<bool>)
    {
        ObjectParameter<bool> boolParam = (ObjectParameter<bool>)param;
        _bindingList.Add(new ItemParameter<bool> { Name = param.Name, Value = boolParam.Default });
    }
    if (param is ObjectParameter<string>)
    {
        ObjectParameter<string> stringParam = (ObjectParameter<string>)param;
        _bindingList.Add(new ItemParameter<string> { Name = param.Name, Value = stringParam.Default });
    }
    if (param is ObjectParameter<int>)
    {
        ObjectParameter<int> intParam = (ObjectParameter<int>)param;
        _bindingList.Add(new ItemParameter<int> { Name = param.Name, Value = intParam.Default });
    }
}
dataGridView1.DataSource = _bindingList;

DataGridView 只显示第一列(名称)。

如何根据参数的类型显示带有单元格的第二列?

【问题讨论】:

  • DataGridView 单元格如何在同一列中显示stringintbool 值的复选框?您可以重新定义您的接口,添加一个string Default {get; } 属性并将_Default 转换为该属性的getter 中的字符串。 BindingList&lt;IItemParameter&gt; 现在可以工作了,你不需要在类型之间切换,只需添加一个新的ItemParameter&lt;Whatever&gt; 而不检查类型。当然,DGV 中显示的值都是只读字符串,除非您提供转换器。 Converter&lt;T&gt; 已经有了委托的通用定义。
  • 当然,如果您想在 UI 中更改 _Default 的值,您还需要一个自定义的 DataGridViewCell,它绘制属性的显示值和提供编辑它的方法(使用自定义EditingControl)。除非您可以将字符串值作为"True""False" 接受bool 类型属性。相反,如果这些值仅用于演示(只读),则无需执行任何其他操作。

标签: winforms datagridview


【解决方案1】:

查看您的代码,我相信您有 2 个问题。第一个是您正在像这样定义绑定列表:

BindingList<IItemParameter>

如果您查看该界面,它只有 1 个属性。名字!

public interface IItemParameter
{
   string Name { get; set; }
}

...所以,这就是您的列表显示的内容!

第二个问题是,这仍然行不通,因为该列的值将属于不同类型(boolstringint)。您可能需要将 T 变量设置为 private,然后使用 public 变量将 T 转换为字符串。

但是,如果这个网格中的数据只是为了显示目的,我会很想做的就是创建一个这样的帮助类:

public class DisplayData
{
    public string Name { get; set; }
    public string Value { get; set; }
}

然后将绑定列表设置为DisplayData 类型,并在您的循环中执行以下操作:

var _bindingList = new BindingList<DisplayData>()

foreach (var param in parameters)
{
    if (param is ObjectParameter<bool>)
    {
        ObjectParameter<bool> boolParam = (ObjectParameter<bool>)param;
        _bindingList.Add(new DisplayData { Name = param.Name, Value = boolParam.Default });
    }
    if (param is ObjectParameter<string>)
    {
        ObjectParameter<string> stringParam = (ObjectParameter<string>)param;
        _bindingList.Add(new DisplayData { Name = param.Name, Value = stringParam.Default });
    }
    if (param is ObjectParameter<int>)
    {
        ObjectParameter<int> intParam = (ObjectParameter<int>)param;
        _bindingList.Add(new DisplayData { Name = param.Name, Value = intParam.Default });
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    相关资源
    最近更新 更多