根据先前的选择重新检查 CheckedListBox

Re-checking a CheckedListBox based on previous selection

我有一个 CheckedListBox,其中填充了键值对,用户可以在其中 select 标签,用于三个不同的选项。

我希望我能说清楚...

用户有三种不同的选择;让我们称它们为 "create 1"、"create 2" 和 "create 3"。对于这些 "creates" 中的每一个,用户可以 select CheckedListBox 中的项目(单击按钮时出现)(这是该特定创建的相应标签)。

代码中发生的事情是:用户select的第一个"Create",和select在CheckedListBox中对应的"tags"。此 selection 存储在 List 变量中。然后用户 selects "Tags" 第二个 "create",再次存储在(不同的)列表中。对于第 3 次创建也是如此。

我想要但无法做到的是,当再次单击第一个创建标签按钮时,出现的 CheckedListBox 应该选中用户首先 selected(选中)的那些项目他的第一个 selection。换句话说,如果 "Create 1" 标签 "x" 和 "y" 被选中,当用户调用 CheckedListBox 时,它们应该重新显示为选中状态。尽管 CheckedListBox 已同时用于 select 标签的标签 - selection of "create 2"。更棘手的是,可以在两者之间添加标签。

所以我希望能够将 CheckedListBox 值与存储在列表变量中的值连接起来,并检查列表中出现的那些项目。

希望它不会太混乱,并且有人知道如何做到这一点。

编辑: 我的表格(部分)的屏幕截图。因此,左上角的每个 "Add" 按钮都会显示底部的面板(其中包含 CheckedListBox 以及其他控件)。在 CheckedListbox 中,"cbTags" 标签被 select 编辑,当 "Done" 按钮被点击时,selection 被存储在一个变量中。单击 "Done" 按钮也会再次隐藏面板。当所有 3 个 "Add" 按钮都被点击,并且相应的标签被 selected 时,有 3 个包含键值对的列表变量。问题是当再次单击这些 "add" 按钮之一时,checkedListBox 应该再次检查这些值(存储在 List 变量之一中)。

Edit2:您还可以在 CheckedListBox 的右侧看到可以将 "Tags" 添加到 CheckedListBox 的控件。我不确定,还没有测试过,但我假设新项目已添加到列表底部,对吗?这意味着列表的索引不会乱序。

没有任何代码源,更难指定要做什么,但正如 Nadia 在评论中建议的那样,我也会建议。每当您要触发一个事件来更改应在 CheckedListBox 项目中显示的标签时,您应该保存已选中项目的索引列表。您的每个 "Create" 选项都应该在某个时候保存这些列表之一。然后,当它们被触发为 re-displayed.

时,将这些标签重置为选中状态

出于演示目的,以下示例是一个简单的 WinForms 应用程序,其中包含三个按钮用于切换显示的 CheckedListBox 内容,另一个按钮用于将其他项目添加到当前显示的列表中。

属性

/// <summary>
/// The index of which dictionary Options are being displayed in the CheckedListBox.
/// </summary>
public int SourceIndex { get; set; }

/// <summary>
/// The array which will contain 3 dictionaries filled with data.
/// </summary>
Dictionary<int, string>[] Options { get; set; }

/// <summary>
/// An array of 3 lists (corrosponding to the Options dictionaries)
/// which will contain the indices of checked Options items.
/// </summary>
List<int>[] Checked { get; set; }

构造函数

/// <summary>
/// Initialize the Options and add content to each.
/// New up the Checked lists.
/// </summary>
public Form1()
{
  InitializeComponent();

  this.SourceIndex = -1;
  this.checkedListBox1.CheckOnClick = true;

  this.Checked = new List<int>[]
  {
    new List<int>(),
    new List<int>(),
    new List<int>(),
  };

  this.Options = new Dictionary<int,string>[3];

  // Fruit Options
  this.Options[0] = new Dictionary<int, string>();
  this.Options[0].Add(0, "Apple");
  this.Options[0].Add(1, "Banana");
  this.Options[0].Add(2, "Orange");
  this.Options[0].Add(3, "Grapes");

  // Meat Options
  this.Options[1] = new Dictionary<int, string>();
  this.Options[1].Add(0, "Beef");
  this.Options[1].Add(1, "Chicken");
  this.Options[1].Add(2, "Pork");
  this.Options[1].Add(3, "Lamb");

  // Drink Options
  this.Options[2] = new Dictionary<int, string>();
  this.Options[2].Add(0, "Milk");
  this.Options[2].Add(1, "Water");
  this.Options[2].Add(2, "Juice");
  this.Options[2].Add(3, "Soda");
}

事件

/// <summary>
/// Save the displayed option's checked items then load the Fruit options to the CheckedListBox.
/// </summary>
/// <param name="sender">Button</param>
/// <param name="e">EventArgs</param>
private void FruitButton_Click(object sender, EventArgs e)
{
  this.SaveCheckedStates();
  this.LoadOptions(0);
}

/// <summary>
/// Save the displayed option's checked items then load the Meat options to the CheckedListBox.
/// </summary>
/// <param name="sender">Button</param>
/// <param name="e">EventArgs</param>
private void MeatButton_Click(object sender, EventArgs e)
{
  this.SaveCheckedStates();
  this.LoadOptions(1);
}

/// <summary>
/// Save the displayed option's checked items then load the Drink options to the CheckedListBox.
/// </summary>
/// <param name="sender">Button</param>
/// <param name="e">EventArgs</param>
private void DrinksButton_Click(object sender, EventArgs e)
{
  this.SaveCheckedStates();
  this.LoadOptions(2);
}

/// <summary>
/// Add an item to the currently displayed Option's items.
/// </summary>
/// <param name="sender">Button</param>
/// <param name="e">EventArgs</param>
private void AddButton_Click(object sender, EventArgs e)
{
  if (!string.IsNullOrEmpty(this.textBox1.Text) && this.SourceIndex >= 0)
  {
    int index = this.Options[this.SourceIndex].Count;
    string text = this.textBox1.Text;
    this.Options[this.SourceIndex].Add(index, text);

    this.SaveCheckedStates();
    this.LoadOptions(this.SourceIndex);
  }
}

私人助手方法

/// <summary>
/// Load the (indexed) Option's items into the CheckedListBox for display.
/// Reset the Checked state for any previously checked.
/// </summary>
/// <param name="index">The index of which Option's items to load.</param>
private void LoadOptions(int index)
{
  this.SourceIndex = index;
  this.checkedListBox1.Items.Clear();

  foreach (KeyValuePair<int, string> item in this.Options[index])
  {
    this.checkedListBox1.Items.Add(item);
  }

  foreach (int i in this.Checked[index])
  {
    this.checkedListBox1.SetItemChecked(i, true);
  }
}

/// <summary>
/// The displayed Options are about to change.
/// Save the currently displayed Option's checked item indices.
/// </summary>
private void SaveCheckedStates()
{
  if (this.SourceIndex >= 0)
  {
    this.Checked[this.SourceIndex].Clear();

    foreach (int i in this.checkedListBox1.CheckedIndices)
    {
      this.Checked[this.SourceIndex].Add(i);
    }
  }
}

结果

总结 一般的想法是每次显示不同的内容时刷新CheckedListBox.Items。您可以找到一种使用数据绑定的方法,但 CheckedListBox 不会友好地接受 Dictionary 作为来源。事实上,foreach 循环就足够了,而且不会太费力。请注意,将项目添加到您的字典不会影响索引顺序,但如果您计划执行任何 inserting/sorting/deleting 选项项目,那么您需要在您的 Checked 索引列表中补偿这些更改。

这只是一个粗略的例子。如果有需要优化的地方,希望有人会编辑它们。