我们需要在NavBarGroup的标题中放置一个复选框(及其标题)。有没有办法做到这一点?
最佳答案
我们创建了一个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);
}
}
}
关于winforms - 如何在NavBarGroup中获取CheckEdit,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6218188/