からクラスを派生させようとしていますGtk.Button
。(まったく使用しないことで)回避できる障害に遭遇しましたOnActivate
が、説明できないため、回避することは安全ではない可能性があります。
から継承するOnActivate
メソッドをオーバーライドすると、ボタンの挙動が変わるようです。Gtk.Button
Gtk.Widget
それはなぜですか、どうすればそれを防ぐことができますか?
そのような効果を達成する唯一の方法は、醜い反射ベースのチェックです。
これがまさに私がしたことであり、問題を再現するために試すことができることです:
これは、カスタム ボタン クラスとそのクラスの 1 つのインスタンスを含む 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
イベントが発生します)。
この変更されたバージョンでは、わずかな変更があります。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();
}
}
}
}
これは、最初のバージョンと意味的に同じである必要があります。しかし、そうではありません - 不可解なことに、アプリケーションの動作が変更されました!
ドキュメントには、「OnActivate
サブクラスでこのメソッドをオーバーライドして、ウィジェットがアクティブ化されたときに通知されるようにします。通常、キー ナビゲーション中にユーザーが Enter キーまたは Space キーを押したときに通知されます。」
ボタンをクリックすると、Clicked
イベントが発生します。ただし、スペース バーを押しても効果がなくなります。コンソールには何も表示されません。
この動作は、.NET の Gtk#、Windows 7 の Mono、Ubuntu の Mono で一貫して再現できました。
ここで何が起こっているのですか?