我正在创建一个类似于TabControl
的自定义控件。我希望标签标题在设计时可以点击,就像TabControl一样。使用我在Microsoft站点上找到的示例代码,我编写了以下代码。它有效,但有一个问题。
对于真实TabControl
,如果在未选择TabControl时单击选项卡标题,则选定的选项卡会更改,并且选中TabControl,显示具有移动手柄和小按钮的调整大小边框用于“TabControl任务”。
使用下面的代码执行相同操作只会更改选定的标签页眉;它不会让我的控件被选中。我想我需要告诉Visual Studio Designer以某种方式选择我的控件。但是如何?
public class MyDesigner : System.Windows.Forms.Design.ControlDesigner
{
private Adorner MyAdorner;
public override void Initialize(IComponent component)
{
base.Initialize(component);
MyAdorner = new Adorner();
this.BehaviorService.Adorners.Add(MyAdorner);
MyAdorner.Glyphs.Add(new MyGlyph(BehaviorService, (MyTabControl)Control));
}
protected override void Dispose(bool disposing)
{
if (disposing && MyAdorner != null)
{
BehaviorService b = BehaviorService;
if (b != null)
{
b.Adorners.Remove(MyAdorner);
}
}
}
class MyGlyph : Glyph
{
MyTabControl TargetControl;
BehaviorService behaviorSvc;
public MyGlyph(BehaviorService behaviorSvc, MyTabControl targetControl)
:base(new ClickingBehaviour())
{
this.behaviorSvc = behaviorSvc;
this.TargetControl = targetControl;
}
private void OnMouseClick(MouseButtons button, Point adornerPoint)
{
var screenPoint = behaviorSvc.AdornerWindowPointToScreen(adornerPoint);
var targetPoint = TargetControl.PointToClient(screenPoint);
TargetControl.DesignTimeClick(button, targetPoint);
}
public override Rectangle Bounds
{
get
{
Point edge = behaviorSvc.ControlToAdornerWindow(TargetControl);
Size size = TargetControl.Size;
Rectangle bounds = new Rectangle(edge, size);
return bounds;
}
}
public override Cursor GetHitTest(Point p)
{
Cursor handled = null;
if (Bounds.Contains(p))
{
var screenPoint = behaviorSvc.AdornerWindowPointToScreen(p);
var targetPoint = TargetControl.PointToClient(screenPoint);
if(TargetControl.IsHeaderArea(targetPoint))
handled = Cursors.Default;
}
return handled;
}
public override void Paint(PaintEventArgs pe)
{
}
class ClickingBehaviour : Behavior
{
public override bool OnMouseDown(Glyph g, MouseButtons button, Point mouseLoc)
{
MyGlyph myG = g as MyGlyph;
myG.OnMouseClick(button, mouseLoc);
return base.OnMouseDown(g, button, mouseLoc);
}
}
}
}
答案 0 :(得分:0)
我无法弄清楚如何使用上面使用Adorner的方法。所以,我使用了Win32消息(我试图避免使用Win32进行互操作)。
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0201 && m.WParam.ToInt32() == 0x0001)
{
var target = (Control as MyTabControl);
if (true) //how to know if focused?
{
var lparam32 = m.LParam.ToInt32();
int lowWord = lparam32 & 0xffff;
int highWord = lparam32 >> 16;
Point p = new Point(lowWord, highWord);
if (target.IsHeaderArea(p))
{
target.DesignTimeClick(MouseButtons.Left, p);
}
}
}
base.WndProc(ref m);
}
它可以工作,但唯一的小问题是当未选中选项卡时,第一次单击时选项卡索引会发生变化。如果未选中实际TabControl
上的选项卡,则不会更改选项卡,只会选择选项卡。但我想我可以忍受这种微小的差异。