예제 #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 (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>
        /// Toggles node state between checked & unchecked
        /// </summary>
        /// <param name="node"></param>
        private void ToggleNodeState(TriStateTreeNode node)
        {
            // no need to toggle state for non-existing node ( or non-tristatetreenode! )
            if (null == node)
            {
                return;
            }

            // toggle state
            CheckState nextState;

            switch (node.CheckState)
            {
            case CheckState.Unchecked:
                nextState = CheckState.Checked;
                break;

            default:
                nextState = CheckState.Unchecked;
                break;
            }

            // notify the treeview that an update is about to take place
            BeginUpdate();

            // update the node state, and dependend nodes
            node.SetCheckedState(nextState);

            // force a redraw
            EndUpdate();
        }
예제 #3
0
        /// <summary>
        /// This method is only called by other nodes so it can be private.
        /// Changes state of the node to the state provided.
        /// </summary>
        /// <param name="newState"></param>
        private void ChangeChildState(CheckState newState)
        {
            // change state
            this._nodeCheckState = newState;

            // change state on the children
            if (this.Nodes != null && this.Nodes.Count > 0)
            {
                foreach (TreeNode node in this.Nodes)
                {
                    TriStateTreeNode tsNode = node as TriStateTreeNode;
                    if (tsNode != null)
                    {
                        tsNode.ChangeChildState(newState);
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// override the aftercheck event in order to get the node beeing checked/unchecked
        /// </summary>
        /// <param name="e"></param>
        protected override void OnAfterCheck(TreeViewEventArgs e)
        {
            TreeNode node = e.Node;

            if (node != null)
            {
                TriStateTreeNode clickedNode = node as TriStateTreeNode;
                if (clickedNode.CheckboxVisible)
                {
                    ToggleNodeState(clickedNode);
                }
                if (null != AfterCheckEx)
                {
                    this.AfterCheckEx(this, e, clickedNode.Checked);
                }
            }

            base.OnAfterCheck(e);
        }
예제 #5
0
        /// <summary>
        /// Draws thee node lines before the checkboxes are drawn
        /// </summary>
        /// <param name="gx">Graphics context</param>
        private void DrawNodeLines(TriStateTreeNode node, Rectangle bounds, Graphics gx)
        {
            // determine type of line to draw
            NodeLineType lineType = node.NodeLineType;

            if (lineType == NodeLineType.None)
            {
                return;
            }

            using (Pen pen = new Pen(SystemColors.ControlDark, 1))
            {
                pen.DashStyle = DashStyle.Dot;

                gx.DrawLine(pen, new Point(bounds.X, bounds.Y + 8), new Point(bounds.X + 15, bounds.Y + 8));
                if (lineType == NodeLineType.WithChildren && node.IsExpanded)
                {
                    gx.DrawLine(pen, new Point(bounds.X + 8, bounds.Y + 8), new Point(bounds.X + 8, bounds.Y + 16));
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Paints the node specified.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="gx"></param>
        private void PaintTreeNode(TriStateTreeNode node, Graphics gx)
        {
            if (this.CheckBoxes)
            {
                // calculate boundaries
                Rectangle ncRect = new Rectangle(node.Bounds.X - 35, node.Bounds.Y, 15, 15);

                // make sure the default checkboxes are gone
                ClearCheckbox(ncRect, gx);

                // draw lines, if we are supposed to
                if (this.ShowLines)
                {
                    DrawNodeLines(node, ncRect, gx);
                }

                if (node.CheckboxVisible)
                {
                    // now draw the checkboxes
                    switch (node.CheckState)
                    {
                    case CheckState.Unchecked:                                                  // Normal
                        DrawCheckbox(ncRect, gx, ButtonState.Normal | ButtonState.Flat);
                        break;

                    case CheckState.Checked:                                                    // Checked
                        DrawCheckbox(ncRect, gx, ButtonState.Checked | ButtonState.Flat);
                        break;

                    case CheckState.Indeterminate:                                      // Pushed
                        DrawCheckbox(ncRect, gx, ButtonState.Pushed | ButtonState.Flat);
                        break;
                    }
                }
            }
        }
예제 #7
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 (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 (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);
                    }
                }
            }
        }