如何编辑 CheckedListBox 中项目的名称?
我有一个 CheckedListBox
,其中包含 X 个项目。这些项目在运行时放置在那里。这些项目应该代表可以在 DataGridView
中显示的报表。我现在需要做的是在报告名称旁边的括号中显示每个报告的记录计数。我尝试编辑该项目的实际名称,但时间不长,但不知道该怎么做。那我就强行强行了。将项目保存到数组中,清除项目,将记录计数附加到数组中的每个项目,创建新项目。好吧,这引起了问题,因为现在它不保留我的支票,原因是每当我生成报告时,我都会清除这些项目并重新创建它们。好吧,有没有人知道如何更改 CheckedListBox
中现有项目的文本,而不是执行另一个 foreach
循环来保存选中状态?
这是我当前拥有的代码:
在 MainForm.Designer.cs 中:
this.clbReports.Items.AddRange(new object[] {
"Report 1",
"Report 2",
"Report 3",
"Report 4",
"Report 5",
"Report 6",
"Report 7",
"Report 8",
"Report 9",
"Report 10",
"Report 11"});
它看起来像:
我想要它看起来像(但不会都是 0):
这是 SelectedIndexChanged 函数:
private void clbReports_SelectedIndexChanged(object sender, EventArgs e)
{
string strCheckBox = clbReports.SelectedItem.ToString();
bool bShowAllIsChecked = clbReports.GetItemChecked(clbReports.FindString("Show All Error Reports"));
bool bSelected = clbReports.GetItemChecked(clbReports.FindString(strCheckBox));
int nIndex = -1;
if (strCheckBox.Contains("Show All Error Reports"))
{
foreach (string str in _strReports)
{
if (!str.Contains("Show All Error Reports") && !str.Contains("Show Tagged Records"))
{
nIndex = clbReports.FindString(str);
if (nIndex > -1)
{
clbReports.SetItemChecked(nIndex, bSelected);
}
}
}
}
else
{
if (strCheckBox.Contains("Show All Error Reports") || bShowAllIsChecked)
{
foreach (string str in _strReports)
{
nIndex = clbReports.FindString(str);
if (nIndex > -1)
{
clbReports.SetItemChecked(nIndex, false);
}
}
}
nIndex = clbReports.FindString(strCheckBox);
if (nIndex > -1)
{
clbReports.SetItemChecked(nIndex, bShowAllIsChecked ? true : bSelected);
}
}
string[] strCheckedItems = new string[clbReports.CheckedItems.Count];
clbReports.CheckedItems.CopyTo(strCheckedItems, 0);
List<string> checkBoxReportFilter = new List<string>();
foreach (ReportRecord obj in this._lstReportRecords)
{
foreach (string str in strCheckedItems)
{
if (str.Contains(obj.Description))
{
checkBoxReportFilter.Add(obj.PartID.ToString());
}
}
}
try
{
if (checkBoxReportFilter.Count == 0 && clbReports.CheckedItems.Count > 0)
{
throw new NullReferenceException();
}
_strReportFilter = String.Join(",", checkBoxReportFilter.ToArray());
}
catch (NullReferenceException)
{
_strReportFilter = "-1";
}
generateReport();
}
这是我清除项目、获取报告计数并创建新项目的代码。
_lstReportRecords = _dataController.ReportList;
bool[] bChecked = new bool[clbReports.Items.Count];
int nCounter = 0;
foreach (string str in _strReports)
{
foreach (string str2 in clbReports.SelectedItems)
{
bChecked[nCounter] = str2.Contains(str);
}
nCounter++;
}
clbReports.Items.Clear();
nCounter = 0;
foreach (string str in _strReports)
{
int nCount = _lstReportRecords.Where<ReportRecord>(delegate(ReportRecord rr) {
return rr.Description == str;
}).Count();
string newReport = str + " (" + nCount + ")";
clbReports.Items.Add(newReport);
clbReports.SetItemChecked(nCounter, bChecked[nCounter]);
nCounter++;
}
请告诉我有一种更简单的方法可以做到这一点。我尝试通过 clbReports.Items 进行 foreach 循环,但它希望我将其转换为字符串(在尝试转换为复选框时出错),因此我无法更改该值。即使我可以将其转换为复选框,我有一种感觉,它会给我错误,即枚举失败,因为列表已更改(或者无论他们如何措辞)。欢迎任何和所有的帮助。谢谢。
编辑:请注意,报告 X 只是为了保持通用性而不会显示实际的报告名称。但是,在代码中,我只是复制并粘贴,因此“显示所有错误报告”和“显示所有标记记录”是我需要检查的报告。
I have a CheckedListBox
that has X number of items. These items are placed there at runtime. These items are supposed to represent reports that can be displayed in the DataGridView
. What I need to do now is display the record count for each report in parenthesis right next to the report name. I tried, not for too long, to edit the actual name of the item but couldn't find out how to do it. So then, I brute forced it. Saved the items to an array, cleared the items, appended the record counts to each item in the array, created new items. Well, this has caused issues because now it's not retaining my checks and the reason why is because whenever I generate the reports, I clear the items and recreate them. Well, rather than doing another foreach
loop to save the checked status, does anyone know of a way to change the text of existing items in a CheckedListBox
?
Here is the code I currently have:
In the MainForm.Designer.cs:
this.clbReports.Items.AddRange(new object[] {
"Report 1",
"Report 2",
"Report 3",
"Report 4",
"Report 5",
"Report 6",
"Report 7",
"Report 8",
"Report 9",
"Report 10",
"Report 11"});
And it looks like:
And I want it to look like (but there won't all be 0's):
Here is the SelectedIndexChanged function:
private void clbReports_SelectedIndexChanged(object sender, EventArgs e)
{
string strCheckBox = clbReports.SelectedItem.ToString();
bool bShowAllIsChecked = clbReports.GetItemChecked(clbReports.FindString("Show All Error Reports"));
bool bSelected = clbReports.GetItemChecked(clbReports.FindString(strCheckBox));
int nIndex = -1;
if (strCheckBox.Contains("Show All Error Reports"))
{
foreach (string str in _strReports)
{
if (!str.Contains("Show All Error Reports") && !str.Contains("Show Tagged Records"))
{
nIndex = clbReports.FindString(str);
if (nIndex > -1)
{
clbReports.SetItemChecked(nIndex, bSelected);
}
}
}
}
else
{
if (strCheckBox.Contains("Show All Error Reports") || bShowAllIsChecked)
{
foreach (string str in _strReports)
{
nIndex = clbReports.FindString(str);
if (nIndex > -1)
{
clbReports.SetItemChecked(nIndex, false);
}
}
}
nIndex = clbReports.FindString(strCheckBox);
if (nIndex > -1)
{
clbReports.SetItemChecked(nIndex, bShowAllIsChecked ? true : bSelected);
}
}
string[] strCheckedItems = new string[clbReports.CheckedItems.Count];
clbReports.CheckedItems.CopyTo(strCheckedItems, 0);
List<string> checkBoxReportFilter = new List<string>();
foreach (ReportRecord obj in this._lstReportRecords)
{
foreach (string str in strCheckedItems)
{
if (str.Contains(obj.Description))
{
checkBoxReportFilter.Add(obj.PartID.ToString());
}
}
}
try
{
if (checkBoxReportFilter.Count == 0 && clbReports.CheckedItems.Count > 0)
{
throw new NullReferenceException();
}
_strReportFilter = String.Join(",", checkBoxReportFilter.ToArray());
}
catch (NullReferenceException)
{
_strReportFilter = "-1";
}
generateReport();
}
And here is the code where I am clearing the items, getting the report counts and creating the new items.
_lstReportRecords = _dataController.ReportList;
bool[] bChecked = new bool[clbReports.Items.Count];
int nCounter = 0;
foreach (string str in _strReports)
{
foreach (string str2 in clbReports.SelectedItems)
{
bChecked[nCounter] = str2.Contains(str);
}
nCounter++;
}
clbReports.Items.Clear();
nCounter = 0;
foreach (string str in _strReports)
{
int nCount = _lstReportRecords.Where<ReportRecord>(delegate(ReportRecord rr) {
return rr.Description == str;
}).Count();
string newReport = str + " (" + nCount + ")";
clbReports.Items.Add(newReport);
clbReports.SetItemChecked(nCounter, bChecked[nCounter]);
nCounter++;
}
Please tell me there is an easier way to do this. I tried doing foreach loops through the clbReports.Items but it wants me to cast it to a string (errored on me when trying to cast to a CheckBox) so I couldn't change the value. And even if I could cast it to a CheckBox, I have a feeling it will give me the error that Enumeration has failed because the list has been changed (or however they word it). Any and all help is welcome. Thanks.
Edit: Please know that the Report X are just so that the actual report names aren't displayed to keep it generic. However, in the code, I just copied and pasted so the Show All Error Reports and Show All Tagged Records are reports I need to check.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正确的(==最简单和最直接的)答案和解决方案是:
是的,这些项目是“对象”类型。不,没人介意,字符串也是一个对象;)
The right ( == most simple and most direct) answer and solution is:
yes, those items are of type "object". No, nobody minds that, string is an object too ;)
如果我是您,我会尝试尝试 INotifyPropertyChanged 接口。
除非必要,否则你不应该扰乱事件。这意味着您不能使用设计器来创建项目,但据我所知,它无论如何都是一个运行时修改的列表...
详细信息:
• 创建一个实现 INotifyPropertyChanged 的类(例如“Foo”) (基本上这会告诉任何侦听器文本属性已更改)。该类将保存所有条目的名称。
• 创建一个ObservableCollection 并将您的CheckedListBox 绑定到该Collection。在 WinForms 中,您必须创建一个 DataBindingSource 并将 Collection 插入到一端,将 ComboBox 插入到另一端。
• 对集合所做的任何更改都将在控件中可见。
华泰
塞比
If I were you, I'd try to give the INotifyPropertyChanged Interface a go.
You Shouldn't mess with events unless necessary. this will mean you can't use the designer to create the items, but as far as I've understood, it's a runtime-modified list anyway...
In detail:
• Create A Class (e.g.'Foo') that Implements INotifyPropertyChanged (Basically this will tell any listener that the text property has changed). This class will hold the names of all entries.
• create an ObservableCollection and bind your CheckedListBox to that Collection. In WinForms you will have to create a DataBindingSource and plug your Collection to one end and the ComboBox to the other end.
• Any change made to the collection will be visible in the control.
HTH
Sebi
为了更改 ListBox(或 CheckedListBox)中的项目,您应该更改这些项目的
ToString()
结果。最简单的解决方案是创建一个“Holder”类,它具有对其所代表的报告的引用。那么 Holder 类的 ToString() 方法应该是这样的:
如果您以某种方式更改
MyReport.RecordCount
(因为报表的记录计数发生变化),您只需调用clbReports.Refresh()
,它会自动显示新值。我认为这样你甚至不需要第二个代码块中的临时数组解决方案;但是,我想建议一种获取项目的选中状态的替代方法。
您可以迭代
clbReports.CheckedIndices
,并仅使用该数组中索引的true
值填充bChecked
数组。In order to change the items in a ListBox (or a CheckedListBox), you should change these items'
ToString()
result.The easiest solution would be to create a "Holder" class, which has a reference to the report it represents. Then the Holder class' ToString() method should be something like this:
If you change
MyReport.RecordCount
somehow (because a report's record count changes), you can just callclbReports.Refresh()
, and it'll automatically show the new value.I think this way you don't even need the temporary array solution in the second code block; however, I'd like to suggest an alternative way of getting the item's checked state.
You can iterate through the
clbReports.CheckedIndices
, and fill yourbChecked
array withtrue
values only for indices in that array.好吧,由于时间有限,我尝试了其他方法。我使用了 ListView,其中 CheckBoxes = true 且 View = List。我还将“显示所有错误报告”和“显示标记记录”删除到列表外部的复选框。这使得实现我想要的功能变得更加容易。这是新代码。
MainForm.Designer.cs
MainForm.cs
向复选框添加计数的代码
感谢大家的帮助和想法。
Well, due to time constraints I tried something else. I went with a ListView where CheckBoxes = true and View = List. I also removed Show All Error Reports and Show Tagged Records to checkboxes outside of the list. This made it a lot easier to do the functions I wanted. Here is the new code.
MainForm.Designer.cs
MainForm.cs
Code to add counts to CheckBoxes
Thank you all for your help and ideas.