如何在NavBarGroup中获取CheckEdit

时间:2011-06-02 17:45:55

标签: winforms devexpress

我们需要在NavBarGroup的标题中放置一个复选框(及其标题)。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:3)

我们创建了一个NavBarGroupChecked类(NavBarGroupChecked.cs),它继承自NavBarGroup,可以直接替换它。它添加了一个RepositoryItemCheckEdit成员,用于跟踪复选框并实现自定义绘制。它有一个Checked属性,告诉您它是否被选中,以及在Checked状态更改时将调用的事件。这就是它。只是投入并工作。

代码低于downloadable here

// built from http://www.devexpress.com/example=E2061

using System;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using DevExpress.XtraEditors.Drawing;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraEditors.ViewInfo;
using DevExpress.XtraNavBar;
using DevExpress.XtraNavBar.ViewInfo;

namespace AutoTagCore.net.windward.controls
{
    /// <summary>
    /// A NavBarGroup that has a check box (with caption) in its header.
    /// </summary>
    public class NavBarGroupChecked : NavBarGroup
    {

        /// <summary>
        /// Occurs when the Checked property value has been changed. 
        /// </summary>
        public event EventHandler CheckedChanged;

        private const int CHECK_BOX_WIDTH = 15;
        private bool isLocked;
        private RepositoryItemCheckEdit _GroupEdit;
        private NavBarControl _NavBarControl;
        private Rectangle hotRectangle;

        /// <summary>
        /// Initializes a new instance of the <see cref="T:DevExpress.XtraNavBar.NavBarGroup"/> class, with the specified caption.
        /// </summary>
        /// <param name="caption">A string representing the NavBar group's caption.</param>
        public NavBarGroupChecked(string caption)
            : base(caption)
        {
            ctor();
        }

        private void ctor()
        {
            GroupEdit = new RepositoryItemCheckEdit { GlyphAlignment = DevExpress.Utils.HorzAlignment.Far };
            GroupEdit.Appearance.Options.UseTextOptions = true;
            GroupEdit.Appearance.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Far;
            GroupEdit.GlyphAlignment = DevExpress.Utils.HorzAlignment.Far;
            ItemChanged += NavBarGroupChecked_ItemChanged;
        }

        private void NavBarGroupChecked_ItemChanged(object sender, System.EventArgs e)
        {
            if (NavBar != NavBarControl)
                NavBarControl = NavBar;
        } 


        /// <summary>
        /// Creates an instance of the <see cref="T:DevExpress.XtraNavBar.NavBarGroup"/> class.
        /// </summary>
        public NavBarGroupChecked()
        {
            ctor();
        }

        /// <summary>
        /// The NavBarControl that owns this. This must be set to work.
        /// </summary>
        private NavBarControl NavBarControl
        {
            get { return _NavBarControl; }
            set { UnsubscribeEvents(value); _NavBarControl = value; SubscribeEvents(value); }
        }

        private void SubscribeEvents(NavBarControl navBarControl)
        {
            if (navBarControl == null)
                return;
            NavBarControl.CustomDrawGroupCaption += NavBarControl_CustomDrawGroupCaption;
            NavBarControl.MouseClick += NavBarControl_MouseClick;
        }

        private void UnsubscribeEvents(NavBarControl navBarControl)
        {
            if (navBarControl != null)
                return;
            NavBarControl.CustomDrawGroupCaption -= NavBarControl_CustomDrawGroupCaption;
            NavBarControl.MouseClick -= NavBarControl_MouseClick;
        }

        /// <summary>
        /// true if the box is checked.
        /// </summary>
        public bool Checked { get; set; }

        /// <summary>
        /// The indent of the check box for the end of the header.
        /// </summary>
        public int CheckIndent { get; set; }

        ///<summary>
        /// The check box displayed in the header.
        ///</summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public RepositoryItemCheckEdit GroupEdit
        {
            get { return _GroupEdit; }
            set { _GroupEdit = value; }
        }

        private Rectangle GetCheckBoxBounds(Rectangle fixedCaptionBounds)
        {
            return new Rectangle(fixedCaptionBounds.Right - CHECK_BOX_WIDTH - CheckIndent, fixedCaptionBounds.Top, CHECK_BOX_WIDTH, fixedCaptionBounds.Height); 
        }

        private bool IsCustomDrawNeeded(NavBarGroup group)
        {
            return GroupEdit != null && NavBarControl != null && !isLocked && group == this;
        }

        private void NavBarControl_CustomDrawGroupCaption(object sender, CustomDrawNavBarElementEventArgs e)
        {
            NavGroupInfoArgs infoArgs = (NavGroupInfoArgs) e.ObjectInfo;
            if (!IsCustomDrawNeeded(infoArgs.Group))
                return;
            try
            {
                isLocked = true;
                BaseNavGroupPainter painter = NavBarControl.View.CreateGroupPainter(NavBarControl);
                Rectangle checkBoxBounds = GetCheckBoxBounds(infoArgs.CaptionBounds);
                painter.DrawObject(infoArgs);
                DrawCheckBox(e.Graphics, checkBoxBounds);
                e.Handled = true;
            }
            finally
            {
                isLocked = false;
            }
        }

        private void DrawCheckBox(Graphics g, Rectangle r)
        {
            BaseEditPainter painter = GroupEdit.CreatePainter();
            BaseEditViewInfo info = GroupEdit.CreateViewInfo();
            info.EditValue = Checked;
            SizeF textBounds = info.Appearance.CalcTextSize(g, GroupEdit.Caption, 500);
            int totalWidth = (int)textBounds.Width + r.Width + 10;
            info.Bounds = new Rectangle(r.Right - totalWidth, r.Y, totalWidth, r.Height);
            info.CalcViewInfo(g);
            ControlGraphicsInfoArgs args = new ControlGraphicsInfoArgs(info, new DevExpress.Utils.Drawing.GraphicsCache(g), r);
            painter.Draw(args);
            args.Cache.Dispose();
        }

        private static NavBarViewInfo GetNavBarView(NavBarControl NavBar)
        {
            PropertyInfo pi = typeof(NavBarControl).GetProperty("ViewInfo", BindingFlags.Instance | BindingFlags.NonPublic);
            return pi.GetValue(NavBar, null) as NavBarViewInfo;
        }

        private bool IsCheckBox(Point p)
        {
            NavBarHitInfo hi = NavBarControl.CalcHitInfo(p);
            if (hi.Group == null || hi.Group != this)
                return false;
            NavBarViewInfo vi = GetNavBarView(NavBarControl);
            vi.Calc(NavBarControl.ClientRectangle);
            NavGroupInfoArgs groupInfo = vi.GetGroupInfo(hi.Group);
            Rectangle checkBounds = GetCheckBoxBounds(groupInfo.CaptionBounds);
            hotRectangle = checkBounds;
            return checkBounds.Contains(p);
        }

        private void NavBarControl_MouseClick(object sender, MouseEventArgs e)
        {
            if (!IsCheckBox(e.Location))
                return;
            Checked = !Checked;
            NavBarControl.Invalidate(hotRectangle);
            if (CheckedChanged != null)
                CheckedChanged(sender, e);
        }
    }
}

答案 1 :(得分:1)

我在解决方案的工作方式上遇到了一些问题并进行了一些小的调整。见下文。

关于如何使用它的示例是;

        private void Form1_Load(object sender, EventArgs e)
    {
        var item = navBarControl1.Groups.Add(new NavBarGroupChecked("NavBarGroupCheckbox", navBarControl1)) as NavBarGroupChecked;
        item.Hint = "my hint";
        item.CheckedChanged += checkchanged;
    }

    private void checkchanged(object sender, EventArgs e)
    {
        MessageBox.Show("It Changed");
    }

这是解决方案:

// built from http://www.devexpress.com/example=E2061

using System;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using DevExpress.XtraEditors.Drawing;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraEditors.ViewInfo;
using DevExpress.XtraNavBar;
using DevExpress.XtraNavBar.ViewInfo;

namespace NavBarCheckTest
{
    /// <summary>
    /// A NavBarGroup that has a check box (with caption) in its header.
    /// </summary>
    public class NavBarGroupChecked : NavBarGroup
    {

        /// <summary>
        /// Occurs when the Checked property value has been changed. 
        /// </summary>
        public event EventHandler CheckedChanged;

        private const int CHECK_BOX_WIDTH = 15;
        private bool isLocked;
        private RepositoryItemCheckEdit _GroupEdit;
        private NavBarControl _NavBarControl;
        private Rectangle hotRectangle;

        /// <summary>
        /// Initializes a new instance of the <see cref="T:DevExpress.XtraNavBar.NavBarGroup"/> class, with the specified caption.
        /// </summary>
        /// <param name="caption">A string representing the NavBar group's caption.</param>
        public NavBarGroupChecked(string caption, NavBarControl parent = null)
            : base(caption)
        {
            ctor(parent);
        }

        private void ctor(NavBarControl parent = null)
        {
            GroupEdit = new RepositoryItemCheckEdit { GlyphAlignment = DevExpress.Utils.HorzAlignment.Far };
            GroupEdit.Caption = string.Empty;
            GroupEdit.Appearance.Options.UseTextOptions = true;
            GroupEdit.Appearance.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Far;
            GroupEdit.GlyphAlignment = DevExpress.Utils.HorzAlignment.Far;
            ItemChanged += NavBarGroupChecked_ItemChanged;
            if (parent != null)
                NavBarControl = parent;
        }

        private void NavBarGroupChecked_ItemChanged(object sender, System.EventArgs e)
        {
            if (NavBar != NavBarControl)
                NavBarControl = NavBar;
        } 


        /// <summary>
        /// Creates an instance of the <see cref="T:DevExpress.XtraNavBar.NavBarGroup"/> class.
        /// </summary>
        public NavBarGroupChecked(NavBarControl parent = null)
        {
            ctor(parent);
        }

        /// <summary>
        /// The NavBarControl that owns this. This must be set to work.
        /// </summary>
        private NavBarControl NavBarControl
        {
            get { return _NavBarControl; }
            set { UnsubscribeEvents(value); _NavBarControl = value; SubscribeEvents(value); }
        }

        private void SubscribeEvents(NavBarControl navBarControl)
        {
            if (navBarControl == null)
                return;
            NavBarControl.CustomDrawGroupCaption += NavBarControl_CustomDrawGroupCaption;
            NavBarControl.MouseClick += NavBarControl_MouseClick;
        }

        private void UnsubscribeEvents(NavBarControl navBarControl)
        {
            if (navBarControl != null)
                return;
            NavBarControl.CustomDrawGroupCaption -= NavBarControl_CustomDrawGroupCaption;
            NavBarControl.MouseClick -= NavBarControl_MouseClick;
        }

        /// <summary>
        /// true if the box is checked.
        /// </summary>
        public bool Checked { get; set; }

        /// <summary>
        /// The indent of the check box for the end of the header.
        /// </summary>
        public int CheckIndent { get; set; }

        ///<summary>
        /// The check box displayed in the header.
        ///</summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public RepositoryItemCheckEdit GroupEdit
        {
            get { return _GroupEdit; }
            set { _GroupEdit = value; }
        }

        private int GetCheckBoxWidth()
        {
            return CheckIndent * 2 + 10;
        }

        //private Rectangle GetCaptionBounds(Rectangle originalCaptionBounds)
        //{
        //    return new Rectangle(originalCaptionBounds.Location, new Size(originalCaptionBounds.Width - GetCheckBoxWidth(), originalCaptionBounds.Height));
        //}

        private Rectangle GetCheckBoxBounds(Rectangle fixedCaptionBounds)
        {
            return new Rectangle(fixedCaptionBounds.Right - CHECK_BOX_WIDTH - CheckIndent, fixedCaptionBounds.Top, CHECK_BOX_WIDTH, fixedCaptionBounds.Height); 
            //return new Rectangle(fixedCaptionBounds.Right, fixedCaptionBounds.Top, GetCheckBoxWidth(), fixedCaptionBounds.Height); ;
        }

        private bool IsCustomDrawNeeded(NavBarGroup group)
        {
            return GroupEdit != null && NavBarControl != null && !isLocked && group == this;
        }

        private void NavBarControl_CustomDrawGroupCaption(object sender, CustomDrawNavBarElementEventArgs e)
        {
            NavGroupInfoArgs infoArgs = (NavGroupInfoArgs) e.ObjectInfo;
            if (!IsCustomDrawNeeded(infoArgs.Group))
                return;
            try
            {
                isLocked = true;
                BaseNavGroupPainter painter = NavBarControl.View.CreateGroupPainter(NavBarControl);

                Rectangle originalCaptionBounds = new Rectangle(infoArgs.CaptionClientBounds.X, infoArgs.CaptionClientBounds.Y, infoArgs.CaptionClientBounds.Width - infoArgs.ButtonBounds.Width, infoArgs.CaptionClientBounds.Height);
                Rectangle checkBoxBounds = GetCheckBoxBounds(originalCaptionBounds);

                painter.DrawObject(infoArgs);
                DrawCheckBox(e.Graphics, checkBoxBounds);
                e.Handled = true;
            }
            finally
            {
                isLocked = false;
            }
        }

        private void DrawCheckBox(Graphics g, Rectangle r)
        {
            BaseEditPainter painter = GroupEdit.CreatePainter();
            BaseEditViewInfo info = GroupEdit.CreateViewInfo();
            info.EditValue = Checked;
            SizeF textBounds = info.Appearance.CalcTextSize(g, GroupEdit.Caption, 500);
            int totalWidth = (int)textBounds.Width + r.Width + 10;
            info.Bounds = new Rectangle(r.Right - totalWidth, r.Y, totalWidth, r.Height);
            info.CalcViewInfo(g);
            ControlGraphicsInfoArgs args = new ControlGraphicsInfoArgs(info, new DevExpress.Utils.Drawing.GraphicsCache(g), r);
            painter.Draw(args);
            args.Cache.Dispose();
        }

        private static NavBarViewInfo GetNavBarView(NavBarControl NavBar)
        {
            PropertyInfo pi = typeof(NavBarControl).GetProperty("ViewInfo", BindingFlags.Instance | BindingFlags.NonPublic);
            return pi.GetValue(NavBar, null) as NavBarViewInfo;
        }

        private bool IsCheckBox(Point p)
        {
            NavBarHitInfo hi = NavBarControl.CalcHitInfo(p);
            if (hi.Group == null || hi.Group != this)
                return false;
            NavBarViewInfo vi = GetNavBarView(NavBarControl);
            vi.Calc(NavBarControl.ClientRectangle);
            NavGroupInfoArgs groupInfo = vi.GetGroupInfo(hi.Group);


            Rectangle originalCaptionBounds = new Rectangle(groupInfo.CaptionClientBounds.X, groupInfo.CaptionClientBounds.Y, groupInfo.CaptionClientBounds.Width - groupInfo.ButtonBounds.Width, groupInfo.CaptionClientBounds.Height);
            Rectangle checkBounds = GetCheckBoxBounds(originalCaptionBounds);

            hotRectangle = checkBounds;
            return checkBounds.Contains(p);
        }

        private void NavBarControl_MouseClick(object sender, MouseEventArgs e)
        {
            if (!IsCheckBox(e.Location))
                return;
            Checked = !Checked;
            NavBarControl.Invalidate(hotRectangle);
            if (CheckedChanged != null)
                CheckedChanged(sender, e);
        }
    }
}