为什么CheckedListBox的SelectedItem的工作方式会有所不同,具体取决于负载均衡的填充方式

本文关键字:负载 取决于 填充 方式 SelectedItem CheckedListBox 工作 方式会 为什么 有所不同 | 更新日期: 2023-09-27 18:34:13

我有两个看起来相同的复选框(除了内容(。我像这样加载一个:

private void PopulateReportsListBox()
{         
    checkedListBoxReports.Items.AddRange(
        ReportSchedulerConstsAndUtils.Reports.ToArray<object>());
}
public static List<string> Reports = new List<string>
{ 
        "Produce Usage", 
        "Delivery Performance",
        "Fill Rate by Customer / Location",
        "Price Compliance"
};

有了这个,我可以得到 CLB 的 ItemCheck 事件中显示的值,如下所示:

private void checkedListBoxReports_ItemCheck(object sender, 
    ItemCheckEventArgs iceargs)
{
    for (int i = 0; i < checkedListBoxReports.Items.Count; ++i)
    {
        if (i != iceargs.Index) checkedListBoxReports.SetItemChecked(i, 
false);
    }
    String selectedRpt = checkedListBoxReports.SelectedItem.ToString();
    DisableParameterGroupBoxes();
    EnableParameterGroupBox(selectedRpt);
}
">

selectedRpt"保存我期望的值(如果选择了第一项,则为"生产使用情况"等(。

但是,我像这样从数据库加载另一个 CLB:

private void PopulateUnitsListBox()
{
    using (SqlConnection con = new 
        SqlConnection(ReportSchedulerConstsAndUtils.CPSConnStr))
    {
        using (SqlCommand cmd = new 
            SqlCommand(ReportSchedulerConstsAndUtils.SelectUnitsQuery, con))
        {
            cmd.CommandType = CommandType.Text;
            using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
            {
                DataTable dt = new DataTable();
                sda.Fill(dt);
                ((ListBox)checkedListBoxUnits).DataSource = dt;
                ((ListBox)checkedListBoxUnits).DisplayMember = "Unit";
                ((ListBox)checkedListBoxUnits).ValueMember = "Unit";
            }
        }
    }
}

。并且我无法访问其 ItemCheck 事件中的显示值。我必须使用CLB的Text proprty而不是SelectedItem.ToString((。如果我使用后者,我会得到(对于所有项目(,"System.Data.DataRowView">

为什么?使用"文本"时,我应该注意任何"陷阱"吗?它可靠吗/我需要修剪((它吗?

为什么CheckedListBox的SelectedItem的工作方式会有所不同,具体取决于负载均衡的填充方式

SelectedItem属性返回集合中用作源的当前选定对象,而不是控件中显示的文本。

CheckedListBox将显示项时,控件首先检查属性DisplayMember,如果对象上不存在指定的属性或 DisplayMember 的值为空字符串,则改为显示对象的 ToString() 方法的结果。

在第一个CheckedListBox中,您将使用对象数组作为项集合,其中元素实际上是字符串,DisplayMember属性为空。因此,项目和显示的文本是相同的,字符串。

在第二个CheckedListBox中,您使用DataTable(您可以将其视为DataRowView的可枚举(作为项目集合,使用 DisplayMember = "Unit"。因此,在这种情况下,SelectedItemDataRowView,显示的文本是成员"Unit"。

如果要始终使用两个"选中列表框"中显示的文本,请使用您在 Text 中所说的属性。此属性获取当前选定项显示的文本(无论源如何(。

private void checkedListBoxReports_ItemCheck(object sender, ItemCheckEventArgs iceargs)
{
    for (int i = 0; i < checkedListBoxReports.Items.Count; ++i)
    {
        if (i != iceargs.Index) 
            checkedListBoxReports.SetItemChecked(i, false);
    }
    string selectedRpt = checkedListBoxReports.Text;
    DisableParameterGroupBoxes();
    EnableParameterGroupBox(selectedRpt);
}

关于您对此属性的担忧:

Text将准确返回函数 ToString() 的值或 DisplayMember 中指定的属性值。

此外,您可以搜索设置此属性的项目,将显示的文本等于指定文本的项目将被选中。

如果 SelectionMode 属性设置为 SelectionMode.MultiExtended ,则此属性返回第一个选定项的文本。

我希望这对你有所帮助。

为什么CheckedListBox的SelectedItem的工作方式会有所不同,具体取决于CLB的填充方式?

它的工作方式并不不同。它始终从 Items 集合或 null 返回对象。这是通往类似事情的捷径

int selectedIndex = listBox.SelectedIndex;
object selectedItem = selectedIndex >= 0 ? listBox.Items[selectedIndex] : null;
">

selectedRpt"保存我期望的值(如果选择了第一项,则为"生产使用情况"等(。

然后

我必须使用 CLB 的 Text 属性而不是 SelectedItem.ToString((。如果我使用后者,我会得到(对于所有项目(,"System.Data.DataRowView">

您不应该首先使用SelectedItem(或任何Items集合项(.ToString()方法来获取显示文本。

控件本身使用一些逻辑来确定文本 - 是的,在某些情况下可能是ToString()方法,但并非总是如此 - 例如DisplayMember属性会更改该行为。

但关键是你不需要知道这个逻辑。该控件公开它在内部使用的方法。它被称为(令人惊讶的(GetItemText

public string GetItemText(
    object item
)

并根据文档

返回指定项的文本表示形式。

还有

如果未指定 DisplayMember 属性,则 GetItemText 返回的值是项的 ToString 方法的值。否则,该方法返回在 item参数中指定的对象的 DisplayMember 属性中指定的成员的字符串值。

简而言之,您应该始终使用该方法。

  • 对于所选项目:

    listBox.GetItemText(listBox.SelectedItem)

  • 对于特定索引:

    listBox.GetItemText(listBox.Items[index])