C# 为什么赢了';设置CheckedSpectName时,t复选标记会出现在TreeListView复选框中(以及如何以编程方式设置复选框)?
我的问题基于sourceforge online docs的C# 为什么赢了';设置CheckedSpectName时,t复选标记会出现在TreeListView复选框中(以及如何以编程方式设置复选框)?,c#,winforms,checkbox,objectlistview,C#,Winforms,Checkbox,Objectlistview,我的问题基于sourceforge online docs的Getting Started一节中提到的ObjectListView 我的目标是在GettingStartedTree项目中的TreeListView的标题列中添加复选框 我可以简单地添加复选框,方法是将treeListView1.checkboxes设置为true并将treeListView1.checkedSpectName设置为Title(请参见下面的更改后的)问题:但是,当我运行程序并单击复选框时,复选标记不会出现在复选框中。
Getting Started
一节中提到的ObjectListView
我的目标是在GettingStartedTree项目中的TreeListView的标题列中添加复选框
我可以简单地添加复选框,方法是将treeListView1.checkboxes
设置为true
并将treeListView1.checkedSpectName
设置为Title
(请参见下面的更改后的)问题:但是,当我运行程序并单击复选框时,复选标记不会出现在复选框中。我希望用户能够“选中”UI上的复选框
注意:如果我将treeListView1.复选框设置为true
并将treeListView1.checkedSpectName
设置为null
,则复选框中不会出现复选标记
我是否正确配置了TreeListView
进行任何更改之前
using System;
using System.Collections.Generic;
namespace ObjectListView_TreeListView
{
class FooTreeListView : BrightIdeasSoftware.TreeListView
{
private List<Categories> categoriesList;
private readonly string[] categoryDescriptors = { "Cat A", "Cat B", "Cat C", "Cat D" };
internal List<Categories> CategoriesList { get => categoriesList; set => categoriesList = value; }
public enum CategoryEnum
{
CategoryA = 0,
CategoryB = 1,
CategoryC = 2,
CategoryD = 3
}
public FooTreeListView() : base()
{
CategoriesList = new List<Categories>();
CategoriesList.Clear();
CanExpandGetter = delegate (Object x)
{
if (x is Categories && ((Categories)x).ItemList.Count > 0)
{
return true;
}
if (x is Categories.Item && ((Categories.Item)x).ActionList.Count > 0)
{return true;
}
return false;
};
ChildrenGetter = delegate (Object x)
{
if (x is Categories)
return ((Categories)x).ItemList;
if (x is Categories.Item)
return ((Categories.Item)x).ActionList;
throw new ArgumentException("Should be Categories or Categories.Item");
};
//Load the 4 top-level categories into the tree
CategoriesList.Add(new Categories(categoryDescriptors[(int)CategoryEnum.CategoryA],false));
CategoriesList.Add(new Categories(categoryDescriptors[(int)CategoryEnum.CategoryB], false));
CategoriesList.Add(new Categories(categoryDescriptors[(int)CategoryEnum.CategoryC], false));
CategoriesList.Add(new Categories(categoryDescriptors[(int)CategoryEnum.CategoryD], false));
}
internal class Categories
{
private string action;
private bool? isChecked;
public string Action { get { return action; } set { action = value; } }
public bool? IsChecked { get => isChecked; set => isChecked = value; }
private List<Item> itemList;
internal List<Item> ItemList { get => itemList; set => itemList = value; }
public Categories(string action, bool? isChecked)
{
this.action = action;
this.isChecked = isChecked;
ItemList = new List<Item>();
}
internal class Item
{
private string action;
private bool? isChecked;
private int numberToKeep = 0;
private List<ItemAction> actionList;
public string Action { get { return action; } set { action = value; } }
public int NumberToKeep { get => numberToKeep; set => numberToKeep = value; }
public bool? IsChecked { get => isChecked; set => isChecked = value; }
internal List<ItemAction> ActionList { get => actionList; set => actionList = value; }
internal Item(string action, bool? isChecked, int numberToKeep)
{
this.action = action;
this.isChecked = isChecked;
this.NumberToKeep = numberToKeep;
ActionList = new List<ItemAction>();
}
internal class ItemAction
{
private string action;
private bool? isChecked;
public string Action { get { return action; } set { action = value; } }
public bool? IsChecked { get { return isChecked; } set { isChecked = value; } }
internal ItemAction(string action, bool? isChecked)
{
this.action = action;
this.isChecked = isChecked;
}
}
}
}
public void AddCategoryItemName(CategoryEnum category, string itemName, bool? isChecked, int numberToKeep)
{
CategoriesList[(int)category].ItemList.Add(new Categories.Item(itemName, isChecked, numberToKeep));
}
public void AddItemAction(CategoryEnum category, string itemName, string action, Boolean isChecked)
{
Categories.Item itemMatch = CategoriesList[(int)category].ItemList.Find(x => x.Action.Equals(itemName));
if (itemMatch != null)
{
itemMatch.ActionList.Add(new Categories.Item.ItemAction(action, isChecked));
}
else
{
throw new ArgumentException(String.Format("Can't find treeviewlist item '{0}'->'{1}'", categoryDescriptors[(int)category], itemName));
}
}
public void AddItemAction(CategoryEnum category, string itemName, string action)
{
Categories.Item itemMatch = CategoriesList[(int)category].ItemList.Find(x => x.Action.Equals(itemName));
if (itemMatch != null)
{
itemMatch.ActionList.Add(new Categories.Item.ItemAction(action, false));
}
else
{
throw new ArgumentException(String.Format("Can't find treeviewlist item '{0}'->'{1}'", categoryDescriptors[(int)category], itemName));
}
}
public void LoadTree()
{
Roots = CategoriesList;
ExpandAll();
}
}
}
using System.Windows.Forms;
using static ObjectListView_TreeListView.FooTreeListView;
namespace ObjectListView_TreeListView
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SuspendLayout();
xenSnapshotsTreeListView1.AddCategoryItemName(CategoryEnum.CategoryA, "Item A", true, 0);
xenSnapshotsTreeListView1.AddCategoryItemName(CategoryEnum.CategoryA, "Item B", false, 1);
xenSnapshotsTreeListView1.AddItemAction(CategoryEnum.CategoryA, "Item A", "Item A foo", true);
xenSnapshotsTreeListView1.AddItemAction(CategoryEnum.CategoryA, "Item A", "Item A bar", false);
xenSnapshotsTreeListView1.AddItemAction(CategoryEnum.CategoryA, "Item B", "Item B foo");
xenSnapshotsTreeListView1.AddItemAction(CategoryEnum.CategoryA, "Item B", "Item B bar", true);
xenSnapshotsTreeListView1.LoadTree();
ResumeLayout();
}
}
}
namespace ObjectListView_TreeListView
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.xenSnapshotsTreeListView1 = new ObjectListView_TreeListView.FooTreeListView();
this.olvColumnAction = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumnNumbSsToKeep = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
((System.ComponentModel.ISupportInitialize)(this.xenSnapshotsTreeListView1)).BeginInit();
this.SuspendLayout();
//
// xenSnapshotsTreeListView1
//
this.xenSnapshotsTreeListView1.AllColumns.Add(this.olvColumnAction);
this.xenSnapshotsTreeListView1.AllColumns.Add(this.olvColumnNumbSsToKeep);
this.xenSnapshotsTreeListView1.CellEditUseWholeCell = false;
this.xenSnapshotsTreeListView1.CheckBoxes = true;
this.xenSnapshotsTreeListView1.CheckedAspectName = "IsChecked";
this.xenSnapshotsTreeListView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.olvColumnAction,
this.olvColumnNumbSsToKeep});
this.xenSnapshotsTreeListView1.Cursor = System.Windows.Forms.Cursors.Default;
this.xenSnapshotsTreeListView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.xenSnapshotsTreeListView1.GridLines = true;
this.xenSnapshotsTreeListView1.Location = new System.Drawing.Point(0, 0);
this.xenSnapshotsTreeListView1.MultiSelect = false;
this.xenSnapshotsTreeListView1.Name = "xenSnapshotsTreeListView1";
this.xenSnapshotsTreeListView1.ShowGroups = false;
this.xenSnapshotsTreeListView1.ShowImagesOnSubItems = true;
this.xenSnapshotsTreeListView1.Size = new System.Drawing.Size(800, 450);
this.xenSnapshotsTreeListView1.TabIndex = 0;
this.xenSnapshotsTreeListView1.UseAlternatingBackColors = true;
this.xenSnapshotsTreeListView1.UseCompatibleStateImageBehavior = false;
this.xenSnapshotsTreeListView1.View = System.Windows.Forms.View.Details;
this.xenSnapshotsTreeListView1.VirtualMode = true;
//
// olvColumnAction
//
this.olvColumnAction.AspectName = "Action";
this.olvColumnAction.Text = "Action";
this.olvColumnAction.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.olvColumnAction.Width = 200;
//
// olvColumnNumbSsToKeep
//
this.olvColumnNumbSsToKeep.AspectName = "NumberToKeep";
this.olvColumnNumbSsToKeep.Text = "# To Keep";
this.olvColumnNumbSsToKeep.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.olvColumnNumbSsToKeep.Width = 65;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.xenSnapshotsTreeListView1);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.xenSnapshotsTreeListView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private FooTreeListView xenSnapshotsTreeListView1;
private BrightIdeasSoftware.OLVColumn olvColumnAction;
private BrightIdeasSoftware.OLVColumn olvColumnNumbSsToKeep;
}
}
树视图1:
OLV列集合,OLV列1(标题):
进行更改后
using System;
using System.Collections.Generic;
namespace ObjectListView_TreeListView
{
class FooTreeListView : BrightIdeasSoftware.TreeListView
{
private List<Categories> categoriesList;
private readonly string[] categoryDescriptors = { "Cat A", "Cat B", "Cat C", "Cat D" };
internal List<Categories> CategoriesList { get => categoriesList; set => categoriesList = value; }
public enum CategoryEnum
{
CategoryA = 0,
CategoryB = 1,
CategoryC = 2,
CategoryD = 3
}
public FooTreeListView() : base()
{
CategoriesList = new List<Categories>();
CategoriesList.Clear();
CanExpandGetter = delegate (Object x)
{
if (x is Categories && ((Categories)x).ItemList.Count > 0)
{
return true;
}
if (x is Categories.Item && ((Categories.Item)x).ActionList.Count > 0)
{return true;
}
return false;
};
ChildrenGetter = delegate (Object x)
{
if (x is Categories)
return ((Categories)x).ItemList;
if (x is Categories.Item)
return ((Categories.Item)x).ActionList;
throw new ArgumentException("Should be Categories or Categories.Item");
};
//Load the 4 top-level categories into the tree
CategoriesList.Add(new Categories(categoryDescriptors[(int)CategoryEnum.CategoryA],false));
CategoriesList.Add(new Categories(categoryDescriptors[(int)CategoryEnum.CategoryB], false));
CategoriesList.Add(new Categories(categoryDescriptors[(int)CategoryEnum.CategoryC], false));
CategoriesList.Add(new Categories(categoryDescriptors[(int)CategoryEnum.CategoryD], false));
}
internal class Categories
{
private string action;
private bool? isChecked;
public string Action { get { return action; } set { action = value; } }
public bool? IsChecked { get => isChecked; set => isChecked = value; }
private List<Item> itemList;
internal List<Item> ItemList { get => itemList; set => itemList = value; }
public Categories(string action, bool? isChecked)
{
this.action = action;
this.isChecked = isChecked;
ItemList = new List<Item>();
}
internal class Item
{
private string action;
private bool? isChecked;
private int numberToKeep = 0;
private List<ItemAction> actionList;
public string Action { get { return action; } set { action = value; } }
public int NumberToKeep { get => numberToKeep; set => numberToKeep = value; }
public bool? IsChecked { get => isChecked; set => isChecked = value; }
internal List<ItemAction> ActionList { get => actionList; set => actionList = value; }
internal Item(string action, bool? isChecked, int numberToKeep)
{
this.action = action;
this.isChecked = isChecked;
this.NumberToKeep = numberToKeep;
ActionList = new List<ItemAction>();
}
internal class ItemAction
{
private string action;
private bool? isChecked;
public string Action { get { return action; } set { action = value; } }
public bool? IsChecked { get { return isChecked; } set { isChecked = value; } }
internal ItemAction(string action, bool? isChecked)
{
this.action = action;
this.isChecked = isChecked;
}
}
}
}
public void AddCategoryItemName(CategoryEnum category, string itemName, bool? isChecked, int numberToKeep)
{
CategoriesList[(int)category].ItemList.Add(new Categories.Item(itemName, isChecked, numberToKeep));
}
public void AddItemAction(CategoryEnum category, string itemName, string action, Boolean isChecked)
{
Categories.Item itemMatch = CategoriesList[(int)category].ItemList.Find(x => x.Action.Equals(itemName));
if (itemMatch != null)
{
itemMatch.ActionList.Add(new Categories.Item.ItemAction(action, isChecked));
}
else
{
throw new ArgumentException(String.Format("Can't find treeviewlist item '{0}'->'{1}'", categoryDescriptors[(int)category], itemName));
}
}
public void AddItemAction(CategoryEnum category, string itemName, string action)
{
Categories.Item itemMatch = CategoriesList[(int)category].ItemList.Find(x => x.Action.Equals(itemName));
if (itemMatch != null)
{
itemMatch.ActionList.Add(new Categories.Item.ItemAction(action, false));
}
else
{
throw new ArgumentException(String.Format("Can't find treeviewlist item '{0}'->'{1}'", categoryDescriptors[(int)category], itemName));
}
}
public void LoadTree()
{
Roots = CategoriesList;
ExpandAll();
}
}
}
using System.Windows.Forms;
using static ObjectListView_TreeListView.FooTreeListView;
namespace ObjectListView_TreeListView
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SuspendLayout();
xenSnapshotsTreeListView1.AddCategoryItemName(CategoryEnum.CategoryA, "Item A", true, 0);
xenSnapshotsTreeListView1.AddCategoryItemName(CategoryEnum.CategoryA, "Item B", false, 1);
xenSnapshotsTreeListView1.AddItemAction(CategoryEnum.CategoryA, "Item A", "Item A foo", true);
xenSnapshotsTreeListView1.AddItemAction(CategoryEnum.CategoryA, "Item A", "Item A bar", false);
xenSnapshotsTreeListView1.AddItemAction(CategoryEnum.CategoryA, "Item B", "Item B foo");
xenSnapshotsTreeListView1.AddItemAction(CategoryEnum.CategoryA, "Item B", "Item B bar", true);
xenSnapshotsTreeListView1.LoadTree();
ResumeLayout();
}
}
}
namespace ObjectListView_TreeListView
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.xenSnapshotsTreeListView1 = new ObjectListView_TreeListView.FooTreeListView();
this.olvColumnAction = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
this.olvColumnNumbSsToKeep = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
((System.ComponentModel.ISupportInitialize)(this.xenSnapshotsTreeListView1)).BeginInit();
this.SuspendLayout();
//
// xenSnapshotsTreeListView1
//
this.xenSnapshotsTreeListView1.AllColumns.Add(this.olvColumnAction);
this.xenSnapshotsTreeListView1.AllColumns.Add(this.olvColumnNumbSsToKeep);
this.xenSnapshotsTreeListView1.CellEditUseWholeCell = false;
this.xenSnapshotsTreeListView1.CheckBoxes = true;
this.xenSnapshotsTreeListView1.CheckedAspectName = "IsChecked";
this.xenSnapshotsTreeListView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.olvColumnAction,
this.olvColumnNumbSsToKeep});
this.xenSnapshotsTreeListView1.Cursor = System.Windows.Forms.Cursors.Default;
this.xenSnapshotsTreeListView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.xenSnapshotsTreeListView1.GridLines = true;
this.xenSnapshotsTreeListView1.Location = new System.Drawing.Point(0, 0);
this.xenSnapshotsTreeListView1.MultiSelect = false;
this.xenSnapshotsTreeListView1.Name = "xenSnapshotsTreeListView1";
this.xenSnapshotsTreeListView1.ShowGroups = false;
this.xenSnapshotsTreeListView1.ShowImagesOnSubItems = true;
this.xenSnapshotsTreeListView1.Size = new System.Drawing.Size(800, 450);
this.xenSnapshotsTreeListView1.TabIndex = 0;
this.xenSnapshotsTreeListView1.UseAlternatingBackColors = true;
this.xenSnapshotsTreeListView1.UseCompatibleStateImageBehavior = false;
this.xenSnapshotsTreeListView1.View = System.Windows.Forms.View.Details;
this.xenSnapshotsTreeListView1.VirtualMode = true;
//
// olvColumnAction
//
this.olvColumnAction.AspectName = "Action";
this.olvColumnAction.Text = "Action";
this.olvColumnAction.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.olvColumnAction.Width = 200;
//
// olvColumnNumbSsToKeep
//
this.olvColumnNumbSsToKeep.AspectName = "NumberToKeep";
this.olvColumnNumbSsToKeep.Text = "# To Keep";
this.olvColumnNumbSsToKeep.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.olvColumnNumbSsToKeep.Width = 65;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.xenSnapshotsTreeListView1);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.xenSnapshotsTreeListView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private FooTreeListView xenSnapshotsTreeListView1;
private BrightIdeasSoftware.OLVColumn olvColumnAction;
private BrightIdeasSoftware.OLVColumn olvColumnNumbSsToKeep;
}
}
树视图1:
OLV列集合,OLV列1(标题):
层次结构复选框
不适用于checkedSpectName
(或checkedSpectGetter
),尽管查找有关该复选框的文档并不容易
以下是一些附加信息:
层次结构复选框
不适用于checkedSpectName
(或checkedSpectGetter
),尽管查找有关该复选框的文档并不容易
以下是一些附加信息:
只是想说明一下
要启用TreeListView
(或任何其他版本的ObjectListView
)的复选框,只需在控件本身上将复选框设置为true
这就是你需要做的
如果模型中有一个属性指示是否应选中某行,则可以通过将checkedSpectName
设置为该属性的名称,将该值自动挂接到复选框上。例如,如果您的模型有一个IsSelected
属性,那么这将使复选框与该属性挂钩:
treeListView1.CheckedAspectName = "IsSelected";
该属性的类型必须为bool
(如果有三态复选框,则为bool?
)。因此,在问题中,将checkedSpectName
设置为“Title”无法工作,因为Title
不是布尔值
不要更改任何列中的任何值以使复选框正常工作
如果使用分层复选框,则不能使用checkedSpectName
或任何其他最终安装CheckStateGetter
的工具。Patrick提到的页面上的文档解释了原因 我只是想说清楚
要启用TreeListView
(或任何其他版本的ObjectListView
)的复选框,只需在控件本身上将复选框设置为true
这就是你需要做的
如果模型中有一个属性指示是否应选中某行,则可以通过将checkedSpectName
设置为该属性的名称,将该值自动挂接到复选框上。例如,如果您的模型有一个IsSelected
属性,那么这将使复选框与该属性挂钩:
treeListView1.CheckedAspectName = "IsSelected";
该属性的类型必须为bool
(如果有三态复选框,则为bool?
)。因此,在问题中,将checkedSpectName
设置为“Title”无法工作,因为Title
不是布尔值
不要更改任何列中的任何值以使复选框正常工作
如果使用分层复选框,则不能使用checkedSpectName
或任何其他最终安装CheckStateGetter
的工具。Patrick提到的页面上的文档解释了原因 更新
在发布这个答案后,我遇到了一个TreeViewList
属性
命名为我以前没有注意到的且我
在ObjectListView
sourceforge文档。我现在相信这就是语法学家所指的
他在帕特里克的评论中回答。在我的代码中(在这个答案中),
该属性设置为false,因此我假设我没有使用
层次结构复选框
。我认为层次复选框是一个模型中的复选框,这个模型有一个层次结构,就像这个答案中我代码中的模型一样
我猜/假设层次结构复选框是
与在,
虽然我不确定ObjectListView
是一个很好的控件。我只希望ObjectListView
sourceforge docs能够更好地区分绘制treeview
部分所需的列表集合,以及在使用和不使用层次结构的情况下向此类模型添加和管理复选框复选框
功能(由属性层次复选框
启用)。我想所有的部分都在文档中,但它分散开来,有点脱节
更新结束
为了清楚起见,我被迫自己回答这个问题
提醒:所有这些都基于原始问题中描述的gettingstartedcode
首先,我最初问题的答案是清除treeview1.checkedSpectName
,如原始示例c所示