Reputation: 20780
I am trying to derive a class from Gtk.Button
. I have encountered an obstacle that I can work around (by not using OnActivate
at all), but that I cannot explain, hence working around it may be unsafe.
It seems that overriding the OnActivate
method that Gtk.Button
inherits from Gtk.Widget
changes the behaviour of the button.
Why is that, and how can I prevent it?
The only way to even achieve such an effect involves some ugly reflection-based checking.
Here's exactly what I did, and what you can try in order to reproduce the issue:
This is a small sample Gtk# application that contains a custom button class and one instance of that class. OnActivate
is not overridden in the custom button class.
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();
}
}
}
}
When the button is clicked, the word clicked will be added in a new line in the console. If the button is focused (which usually is the case, as it is the only focusable element in the window), and the user presses the space bar, the same happens, as expected (i.e. the Clicked
event is fired).
In this modified version, there is a slight alteration: The MyButton
class now overrides the OnActivate
method, but the overridden version does nothing beside calling the inherited version of the method:
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();
}
}
}
}
This should be semantically the same as the first version. Yet, it is not - inexplicably, the behaviour of the application has changed!
The docs just say about 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."
Clicking the button still fires the Clicked
event. However, pressing the space bar has no effect any more; nothing appears in the console.
I could consistently reproduce this behaviour with Gtk# for .NET, Mono on Windows 7 and Mono on Ubuntu.
What is going on here?
Upvotes: 1
Views: 153
Reputation: 58822
That's an interesting question. Unfortunately I can't give a definitive answer about the precise cause. Even though I have looked into the gtk# source I was quickly lost in the jungle of default signal handlers, klasses and gtypes.
If you are just looking for the solution, though, I can tell you that: you should be overriding the OnActivated
method (with a d
at the end).
Upvotes: 2