为什么重写Gtk.Widget.OnActivate()更改窗口小部件的行为?
我试图从Gtk.Button派生一个类 . 我遇到了一个障碍,我可以解决(根本不使用 OnActivate
),但我无法解释,因此解决它可能是不安全的 .
似乎覆盖了 Gtk.Button
从 Gtk.Widget
继承的OnActivate method改变了按钮的行为 .
Why is that, and how can I prevent it?
实现这种效果的唯一方法是进行一些难看的基于反射的检查 .
这正是我所做的,以及你可以尝试重现的问题:
这是一个小样本Gtk#应用程序,它包含一个自定义按钮类和该类的一个实例 . OnActivate
未在自定义按钮类中重写 .
using System;
using Gtk;
namespace ButtonOnActivateExample
{
class Program
{
private class MyButton : Button
{
public MyButton()
{
}
public MyButton(IntPtr raw)
{
}
}
[STAThread]
public static void Main(string[] args)
{
Application.Init();
using (Window win = new Window("OnActivate Test")) {
win.SetSizeRequest(300, 200);
win.Hidden += delegate(object sender, EventArgs e) {
Application.Quit();
};
MyButton btn = new MyButton();
btn.Clicked += delegate {
Console.WriteLine("clicked");
};
win.Add(btn);
win.ShowAll();
Application.Run();
win.Destroy();
}
}
}
}
单击该按钮时,单击的单词将添加到控制台的新行中 . 如果按钮被聚焦(通常是这种情况,因为它是窗口中唯一的可聚焦元素),并且用户按下空格键,则会发生同样的事情(即Clicked event被触发) .
在这个修改版本中,有一个小的改动: MyButton
类现在覆盖了 OnActivate
方法,但被覆盖的版本除了调用该方法的继承版本之外什么都不做:
using System;
using Gtk;
namespace ButtonOnActivateExample
{
class Program
{
private class MyButton : Button
{
public MyButton()
{
}
public MyButton(IntPtr raw)
{
}
protected override void OnActivate()
{
base.OnActivate();
}
}
[STAThread]
public static void Main(string[] args)
{
Application.Init();
using (Window win = new Window("OnActivate Test")) {
win.SetSizeRequest(300, 200);
win.Hidden += delegate(object sender, EventArgs e) {
Application.Quit();
};
MyButton btn = new MyButton();
btn.Clicked += delegate {
Console.WriteLine("clicked");
};
win.Add(btn);
win.ShowAll();
Application.Run();
win.Destroy();
}
}
}
}
这应该在语义上与第一个版本相同 . 然而,它并非 - 莫名其妙地,应用程序的行为已经改变了!
docs只是说 OnActivate
:"Override this method in a subclass to be notified when the widget is activated, commonly when the user presses Enter or Space during key navigation."
单击该按钮仍会触发 Clicked
事件 . 但是,按空格键不再有效;控制台中没有任何内容 .
我可以用Gtk#for .NET,Windows 7上的Mono和Ubuntu上的Mono来持续重现这种行为 .
What is going on here?
2 years ago
这是一个有趣的问题 . 不幸的是,我无法就确切的原因给出明确的答案 . 即使我已经查看了gtk#source,我很快就在默认信号处理程序,类和gtypes的丛林中迷失了 .
但是,如果您只是在寻找解决方案,我可以告诉您:您应该重写
OnActivated
方法(最后使用d
) .