繁体   English   中英

从子类值设置DataGridView单元格值

[英]Set DataGridView Cell Value from a SubClass Value

假设我有一个像下面这样的课:

public class Origin {
    public Origin(bool isAllowed, bool isGloballyAllowed) {
        IsAllowed = isAllowed;
        IsGloballyAllowed = isGloballyAllowed;
    }

    public bool IsAllowed { get; set; }
    public bool IsGloballyAllowed { get; set; }
}

public class OriginSet {
    public OriginSet() {
        OriginType = originType;
        OriginData_A = originDataA;
        OriginData_B = originDataB;
        OriginData_C = originDataC;
    }

    public string OriginType { get; set; }
    public Origin OriginData_A { get; set; }
    public Origin OriginData_B { get; set; }
    public Origin OriginData_C { get; set; }
}

我有一个List<OriginSet>变量,具有以下值:

var originList = new List<OriginSet> {
    new OriginSet("Origin 1", new Origin(true, true), new Origin(true, false), new Origin(false, false),
    new OriginSet("Origin 2", new Origin(false, false), new Origin(true, false), new Origin(true, true)
};

如何在具有以下布局的DataGridView中显示它:

在此处输入图片说明

这个想法是,DataGridView中的CheckBoxes启用了它们的ThreeState属性,以便可以使用3个不同的值,而它取决于OriginSet类的属性的Origin类的值,如下所示:

(IsAllowed = TRUE and IsGloballyAllowed = TRUE) THEN CheckBox is Checked
(IsAllowed = TRUE and IsGloballyAllowed = FALSE) THEN CheckBox is Indeterminate
(IsAllowed = FALSE and IsGloballyAllowed = FALSE) THEN CheckBox is Unchecked

我想伸出援手,因为这是我第一次做这样的事情,即使它是允许的。 我尝试查找Google,但没有结果与我的具体问题匹配。

但是,您尝试做的是可行的; 我猜您可能不得不采取不同的方法。

看图片,特别是“数据A”列是一个复选框列。 此列中的每个复选框单元格都是绑定到Origin对象的数据。 Origin对象具有两(2)个bool属性: IsAllowedIsGloballyAllowed. 即使网格已公开,网格也不会知道要显示哪个网格。 此外,您描述的“逻辑”…

(IsAllowed = TRUE and IsGloballyAllowed = TRUE) THEN CheckBox is Checked
(IsAllowed = TRUE and IsGloballyAllowed = FALSE) THEN CheckBox is Indeterminate
(IsAllowed = FALSE and IsGloballyAllowed = FALSE) THEN CheckBox is Unchecked

Origin类别中缺少。 这里的要点是,复选框单元格只能取一(1)的值,并提供二(2)的值。 上面的逻辑是您需要实现以返回所需检查状态的逻辑。 下面的Origin类演示了一种实现此目的的方法。

class Origin {
  public bool IsAllowed { get; set; }
  public bool IsGloballyAllowed { get; set; }

  public Origin(bool isAllowed, bool isGloballyAllowed) {
    IsAllowed = isAllowed;
    IsGloballyAllowed = isGloballyAllowed;
  }

  public bool? CheckState {
    get {
      if (IsAllowed && IsGloballyAllowed)
        return true;
      if (!IsAllowed && !IsGloballyAllowed)
        return false;
      //if (IsAllowed == true && IsGloballyAllowed == false)
      //  return null;
      return null;
    }
  }
}

添加了一个getter / property方法CheckState ,该方法返回一个可为null的布尔值: truefalsenull这是OriginSet类可用于将CheckedState暴露于DatagridView并正确设置复选框的属性。 因此,在OriginSet类中需要一些更改。

OriginSet类中,已经知道将Origin对象“暴露”到单元格将不起作用。 因此,一种可行的解决方案是创建有效的bool? 暴露于网格时“将”工作的变量复选框。 一旦添加到类中,然后使用每个Origin对象的CheckState属性在构造函数中初始化,我们就可以使用变量正确设置复选框。

class OriginSet {
  public string OriginType { get; set; }
  public Origin OriginData_A { get; set; }
  public Origin OriginData_B { get; set; }
  public Origin OriginData_C { get; set; }
  public bool? originA_State { get; set; }
  public bool? originB_State { get; set; }
  public bool? originC_State { get; set; }

  public OriginSet(string originType, Origin originDataA, Origin originDataB, Origin originDataC) {
    OriginType = originType;
    OriginData_A = originDataA;
    OriginData_B = originDataB;
    OriginData_C = originDataC;
    originA_State = originDataA.CheckState;
    originB_State = originDataB.CheckState;
    originC_State = originDataC.CheckState;
  }
}

进行了这些更改之后,所需要做的就是正确设置DataGridview列。 这里没有什么要紧的,但重要的一点是,当将一列添加到网格时,除了将ThreeState设置为true以启用null值之外,其DataPropertyName必须与OriginSet类中的属性名称匹配。 最后,将AutoGenerateColumns设置为false,以防止网格尝试显示OriginSet类中的所有“公共/公开”属性。

List<OriginSet> originList;

public Form1() {
  InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {
  FillList();
  SetGridProperties();
  dataGridView1.DataSource = originList;
}

private void FillList() {
  originList = new List<OriginSet> {
    new OriginSet("Origin 0", new Origin(true, true), new Origin(true, true), new Origin(true, true)),
    new OriginSet("Origin 1", new Origin(true, false), new Origin(true, false), new Origin(true, false)),
    new OriginSet("Origin 2", new Origin(false, false), new Origin(false, false), new Origin(false, false))
  };
}

private void SetGridProperties() {
  DataGridViewTextBoxColumn txtCol = new DataGridViewTextBoxColumn();
  txtCol.HeaderText = "Origin";
  txtCol.DataPropertyName = "OriginType";
  dataGridView1.Columns.Add(txtCol);
  dataGridView1.Columns.Add(GetCheckBoxCol("Data A", "originA_State"));
  dataGridView1.Columns.Add(GetCheckBoxCol("Data B", "originB_State"));
  dataGridView1.Columns.Add(GetCheckBoxCol("Data C", "originC_State"));
  dataGridView1.AutoGenerateColumns = false;
}

private DataGridViewCheckBoxColumn GetCheckBoxCol(string name, string dataname) {
  DataGridViewCheckBoxColumn chckCol = new DataGridViewCheckBoxColumn();
  chckCol.Name = name;
  chckCol.DataPropertyName = dataname;
  chckCol.ThreeState = true;
  return chckCol;
}

应该开始清楚这里可能存在问题。 问题是,如果用户“更改”复选框,您打算怎么做? 这些复选框由初始值isAllowedisGloballyAllowed ……此处的要点是,当用户“更改”一个复选框时,初始的“逻辑”以“设置” CheckState将变为“中断”。 如果您想保持此逻辑正确(我认为是正确的),则您将不得不做更多的工作来维护该“逻辑”。

希望这有意义并有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM