Пример #1
0
        /// <summary>
        /// This method is only called when a node's state has been changed through the
        /// Checked property
        /// </summary>
        /// <param name="oldState">Previous state</param>
        /// <param name="newState">New state</param>
        private void CheckStateChanged(CheckState oldState, CheckState newState)
        {
            // States are equal?
            if (newState != oldState)
            {
                // not equal.
                // modify state
                this._nodeCheckState = newState;

                // change state of the children
                if (this.Nodes != null && this.Nodes.Count > 0)
                {
                    foreach (System.Windows.Forms.TreeNode node in this.Nodes)
                    {
                        TriStateTreeNode tsNode = node as TriStateTreeNode;
                        if (tsNode != null)
                        {
                            tsNode.ChangeChildState(newState);
                        }
                    }
                }

                // notify the parent of the changed state.
                if (this.Parent != null)
                {
                    TriStateTreeNode parentNode = this.Parent as TriStateTreeNode;
                    if (parentNode != null)
                    {
                        parentNode.ChildCheckStateChanged(this._nodeCheckState);
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Private method that is called by one of the childnodes in order to report a
        /// change in state.
        /// </summary>
        /// <param name="childNewState">New state of the childnode in question</param>
        private void ChildCheckStateChanged(CheckState childNewState)
        {
            bool       notifyParent = false;
            CheckState currentState = this._nodeCheckState;
            CheckState newState     = this._nodeCheckState;

            // take action based on the child's new state
            switch (childNewState)
            {
            case CheckState.Indeterminate:     // child state changed to indeterminate
                // if one of the children's state changes to indeterminate,
                // it's parent should do the same, if it is a container too!.
                if (IsContainer)
                {
                    newState = CheckState.Indeterminate;

                    // the same is valid for this node's parent.
                    // check if this node's state has changed and inform the parent
                    // if this is the case
                    notifyParent = (newState != currentState);
                }
                break;

            case CheckState.Checked:
                // One of the child nodes was checked so we must check:
                // 1) if the child node is the only child node, our state becomes checked too.
                // 2) if there are children with a state other then checked, our state
                //    must become indeterminate if this is a container.
                if (this.Nodes.Count == 1)     // if there is only one child, our state changes too!
                {
                    // set our state to checked too and set the flag for
                    // parent notification.
                    newState     = CheckState.Checked;
                    notifyParent = true;
                    break;
                }

                // set to checked by default
                // if this is not a container, there is no need to check further
                newState = CheckState.Checked;
                if (!IsContainer)
                {
                    notifyParent = (newState != currentState);
                    break;
                }

                // traverse all child nodes to see if there are any with a state other then
                // checked. if so, change state to indeterminate.
                foreach (System.Windows.Forms.TreeNode node in this.Nodes)
                {
                    TriStateTreeNode checkedNode = node as TriStateTreeNode;
                    if (checkedNode != null && checkedNode.CheckState != CheckState.Checked)
                    {
                        newState = CheckState.Indeterminate;
                        break;
                    }
                }

                // set notification flag if our state has to be changed too
                notifyParent = (newState != currentState);
                break;

            case CheckState.Unchecked:
                // For nodes that are no containers, a child being unchecked is not relevant.
                // so we can exit at this point.
                if (!IsContainer)
                {
                    break;
                }

                // A child's state has changed to unchecked so check:
                // 1) if this is the only child. if so, uncheck this node too, if it is a container, and set
                //	  notification flag for the parent.
                // 2) Check if there are child nodes with a state other then unchecked.
                //	  if so, change our state to indeterminate.
                if (this.Nodes.Count == 1)
                {
                    // synchronize state with only child.
                    // set notification flag
                    newState     = CheckState.Unchecked;
                    notifyParent = true;
                    break;
                }

                // set to unchecked by default
                newState = CheckState.Unchecked;

                // if there is a child with a state other then unchecked,
                // our state must become indeterminate.
                foreach (System.Windows.Forms.TreeNode node in this.Nodes)
                {
                    TriStateTreeNode checkedNode = node as TriStateTreeNode;
                    if (checkedNode != null && checkedNode.CheckState != CheckState.Unchecked)
                    {
                        newState = CheckState.Indeterminate;
                        break;
                    }
                }

                // notify the parent only if our state is about to be changed too.
                notifyParent = (newState != currentState);
                break;
            }

            // should we notify the parent? ( has our state changed? )
            if (notifyParent)
            {
                // change state
                this._nodeCheckState = newState;

                // notify parent
                if (this.Parent != null)
                {
                    TriStateTreeNode parentNode = this.Parent as TriStateTreeNode;
                    if (parentNode != null)
                    {
                        // call the same method on the parent.
                        parentNode.ChildCheckStateChanged(this._nodeCheckState);
                    }
                }
            }
        }