从子类值设置DataGridView单元格值

时间:2018-06-07 02:01:56

标签: c# datagridview subclass

假设我有一个类如下:

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中显示它:

enter image description here

这个想法是DataGridView中的CheckBoxes启用了它们的ThreeState属性,因此它有3个不同的值,而它取决于作为属性的Origin类的值OriginSet班级,如下所示:

(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

我想寻求一些帮助,因为这是我第一次做这样的事情,如果它是可以允许的话。我试过查找谷歌,但没有结果符合我的具体问题。

1 个答案:

答案 0 :(得分:0)

你要做的事情是可行的;我猜你可能不得不采取不同的方式。

查看图片,特别是“数据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,它返回一个可以为空的bool: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列。这里不多,但重要的一点是,在向网格添加列时,除了将DataPropertyName设置为true之外,OriginSet必须与ThreeState类中的属性名称匹配启用null值。最后将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的初始“逻辑”将在用户“变为”时“更改“其中一个复选框。如果你想保持这种逻辑正确,我认为你会这样做,你将不得不做更多的工作来维持这种“逻辑”。

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