Почему флажки не отображаются в флажке TreeListView, если задано имя CheckedAspectName (и как я могу программно установить флажки)? - PullRequest
0 голосов
/ 09 ноября 2018

Мой вопрос основан на ObjectListView коде Gettingstarted (проект GettingStartedTree) , указанном в разделе Getting Started ObjectListView онлайн-документации sourceforge.

Моя цель - добавить checkboxes в столбец Заголовок TreeListView в проекте GettingStartedTree.

Я смог добавить флажки, просто установив treeListView1.CheckBoxes в true и установив treeListView1.CheckedAspectName в Title (см. After making changes ниже), как описано в инструкциях. Проблема: Однако, когда я запускаю программу и нажимаю на флажок, флажок не появляется в флажке. Я ожидаю, что пользователь должен иметь возможность «поставить галочку» в пользовательском интерфейсе.

Примечание. Если я оставлю treeListView1.CheckBoxes установленным на true и установим treeListView1.CheckedAspectName на null, тогда флажок действительно появится в поле.

Правильно ли я настраиваю TreeListView?

Перед внесением любых изменений

treeListView1:

CheckBoxes = false
CheckedAspectName = null

OLVColumn Collection, olvColumn1 (название):

Name = olvColumn1
AspectName = Title
CheckBoxes = false (Title column)

enter image description here

После внесения изменений

treeListView1:

CheckBoxes = true
CheckedAspectName = Title

OLVColumn Collection, olvColumn1 (название):

Name = olvColumn1
AspectName = Title
CheckBoxes = false (Title column)

enter image description here

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Просто чтобы прояснить это ...

Чтобы включить флажки для TreeListView (или любой другой версии ObjectListView), просто установите CheckBoxes на true на самом элементе управления.

Это все, что тебе нужно сделать.

Если в вашей модели есть свойство, указывающее, следует ли проверять строку или нет, вы можете автоматически подключить это значение к флажкам, установив CheckedAspectName в качестве имени этого свойства. Например, если ваша модель имеет свойство IsSelected, то этот флажок будет привязан к этому свойству:

treeListView1.CheckedAspectName = "IsSelected";

Тип этого свойства должен быть bool (или bool?, если у вас есть флажок с тремя состояниями). Таким образом, в вопросе установка CheckedAspectName на «Заголовок» не может работать, поскольку Title не является логическим значением.

Не изменяйте никакие значения в столбцах , чтобы установить флажки.

Если вы используете иерархические флажки, вы не можете использовать CheckedAspectName или что-либо еще, что в конечном итоге устанавливает CheckStateGetter. Документы на странице Иерархия с флажками , которые упоминал Патрик, объясняют, почему.

0 голосов
/ 09 ноября 2018

Обновление

После публикации этого ответа я наткнулся на свойство 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 элемент управления

enter image description here

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;
    }
}
0 голосов
/ 09 ноября 2018

HierarchicalCheckboxes не работает с CheckedAspectName (или CheckedAspectGetter), хотя найти документацию по этому нелегко.

Некоторая дополнительная информация здесь:

Флажки с учетом иерархии

...