3 Stimmen

Wie kann ich ein CheckEdit in einer NavBarGroup erhalten?

Wir müssen ein Kontrollkästchen (und eine Beschriftung dafür) in der Kopfzeile einer NavBarGroup platzieren. Gibt es eine Möglichkeit, dies zu tun?

3voto

David Thielen Punkte 24913

Wir haben eine NavBarGroupChecked-Klasse (NavBarGroupChecked.cs) erstellt, die von NavBarGroup erbt und einfach als Ersatz eingefügt werden kann. Sie fügt ein RepositoryItemCheckEdit-Mitglied hinzu, das das Kontrollkästchen verfolgt und eine benutzerdefinierte Zeichnung implementiert. Es hat eine Checked-Eigenschaft, die Ihnen mitteilt, ob es markiert ist, und ein Ereignis, das aufgerufen wird, wenn sich der Checked-Status ändert. Das war's auch schon. Wird einfach eingefügt und funktioniert.

Der Code ist unten und auch hier zum Herunterladen .

// 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);
        }
    }
}

1voto

rlev Punkte 13

Ich hatte einige Probleme mit der Art und Weise, wie diese Lösung funktionierte, und nahm einige kleinere Änderungen vor. Siehe unten.

Ein Beispiel für die Verwendung dieser Methode ist;

        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");
    }

Dies ist die Lösung:

// 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);
        }
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X