Обновление
После публикации этого ответа я наткнулся на свойство TreeViewList
по имени HierarchicalCheckboxes
, который я не заметил раньше, и что я
не вижу обсуждаемых / описанных где-либо в ObjectListView
SourceForge документы. Теперь я считаю, что это то, что грамматик имел в виду
чтобы в своем комментарии под Патриксом ответить. В моем коде (в этом ответе)
это свойство установлено в false, поэтому я предполагаю, что я НЕ , используя
HierarchicalCheckboxes
. Я думал, что иерархические флажки были флажками в модели, которая имеет иерархическую структуру, подобную модели в моем коде в этом ответе.
Я предполагаю / предполагаю HierarchicalCheckboxes
это
связанные с записью на флажки с учетом иерархии ,
хотя я не уверен ObjectListView
отличный контроль. Я просто хотел бы, чтобы документы ObjectListView
sourceforge проделали лучшую работу, дифференцируя объяснение набора списков, необходимых для рисования части treeview
TreeListView
вместе с добавлением и управлением флажками в такой модели как с использованием, так и без использования. функции hierarchical checkboxes
(включается свойством HierarchicalCheckboxes
). Я предполагаю, что все части находятся в документах, но это распространено и немного разъединено.
Конец обновления
Ради ясности я был вынужден ответить на это сам .....
Напоминание: все это основано на gettingstartedcode
, описанном в оригинальном вопросе.
Во-первых, ответом на мою первоначальную проблему было очистить treeview1.CheckedAspectName
, как в исходном примере кода. Это привело к появлению флажка в флажке (как и ожидалось) при нажатии флажка.
Грамматик любезно описал, как программно установить / снять флажок для (я предполагаю) сценария non-hierarchical checkbox
, т. Е. Добавить свойство bool?
или bool
в модель и добавить имя свойства в свойство CheckedAspectName TreeListView. ,
Я пришел к выводу, что это не сработает для hierarchical checkboxes
, потому что Грамматик сказал следующее, и на основании его объяснения требуется загрузка имени свойства bool?
или bool
в CheckedAspectName,
Если вы используете иерархические флажки, вы не можете использовать
CheckedAspectName или что-нибудь еще, что в конечном итоге устанавливает
CheckStateGetter
Таким образом, игнорируя рекомендацию о том, что установка свойства CheckedAspectName для hierarchical checkboxes
не будет работать, я реализовал свойство isChecked bool?
на всех уровнях в моей иерархической модели. Он работает нормально, то есть теперь я могу программно установить флажок на любом уровне иерархии через модель.
Ниже приведен код для простого примера (мне нужно написать код, чтобы установить флажок с тремя состояниями для родительских строк на основе проверенных или непроверенных дочерних строк.). Столбец "# Сохранить" предназначен для использования только для элементов уровня 2 в иерархии
Форма имеет только FooTreeListView : BrightIdeasSoftware.TreeListView
элемент управления
FooTreeListView.cs
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();
}
}
}
Form1.cs
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();
}
}
}
Form1.Designer.cs
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;
}
}