上下文
我正在将C / GTK + GUI应用程序转换为C#。我在VS2017中使用了GTKSharp绑定版本3.22.0。
应用程序声明了几个信号,如
g_signal_new ("SIG_NAME", params...);
并通过g_signal_emit_by_name(... "SIG_NAME"...)
发出。
问题
我无法找到将该行为转换为GTK#的方法。
我查看了GTK#的源代码,看看如何定义和处理自定义信号,如here,但我无法模仿那里实现的行为。
方法
我尝试过定义这样的自定义对象:
using System;
using Gtk;
public class MyApp
{
public class MyCustomObj : GLib.Object
{
public delegate void MyDelegateSignalHandler(int arg0, int arg1);
public delegate void MyDelegate(int arg0, int arg1);
public class MyDelegateArgs : GLib.SignalArgs
{
public int a { get; set; }
}
public MyCustomObj() : base()
{}
[GLib.Signal("MyEvent")]
public event MyDelegate MyDelegateEvent
{
add
{
GLib.Object.GetObject(Handle).AddSignalHandler("MyEvent", value, new MyDelegateSignalHandler((a, b) => { }));
}
remove
{
GLib.Object.GetObject(Handle).RemoveSignalHandler("MyEvent", value);
}
}
}
public static void Main(string[] args)
{
MyCustomObj newObj = new MyCustomObj();
newObj.MyDelegateEvent += new MyCustomObj.MyDelegate((a, b) => { });
GLib.Signal.Emit(newObj, "MyEvent", 1, 2);
}
}
那是:
GLib
对象类型MyCustomObj
MyDelegate
事件MyCustomObj
的实例,并将回调附加到其新事件MyEvent
信号。然而,当调用AddSignalHandler()
时,GTK对此不太满意:
(CustomSignal.exe:9276): GLib-GObject-[1;33mWARNING[0m **: ../../glib-2.50.2/gobject/gsignal.c:2423: signal 'MyEvent' is invalid for instance '05cc4000' of type '__gtksharp_0_MyApp+2bMyCustomObj'
因此GLib.Signal.Emit
报告
Invalid signal name: MyEvent
但是,GObject的定义以这种方式使用AddSignalHandler
:
public void AddNotification (string property, NotifyHandler handler)
{
AddSignalHandler ("notify::" + property, handler, typeof(NotifyArgs));
}
所以看起来名为notify::<whatever>
的信号处理得很好。我们试试这个:
public class MyCustomObj : GLib.Object
{
public MyCustomObj() : base()
{}
[GLib.Signal("notify::abc")]
public event GLib.NotifyHandler MyDelegateEvent
{
add
{
GLib.Object.GetObject(Handle).AddSignalHandler("notify::abc", value, typeof(GLib.NotifyArgs));
}
remove
{
GLib.Object.GetObject(Handle).RemoveSignalHandler("notify::acb", value);
}
}
}
public static void Main(string[] args)
{
MyCustomObj newObj = new MyCustomObj();
newObj.MyDelegateEvent += new GLib.NotifyHandler((o, e) => { Console.WriteLine("Signal received"); });
GLib.Signal.Emit(newObj, "notify::abc");
Console.ReadLine();
}
这实际上有效。此外,[GLib.Signal("notify::abc")]
是不必要的,因为信号被正确地登记和处理。 将信号名称重命名为非notify::...
的任何内容,但会导致应用程序发出通常的警告:
(CustomSignal.exe:9276): GLib-GObject-[1;33mWARNING[0m **: ../../glib-2.50.2/gobject/gsignal.c:2423: signal '...' is invalid for instance '05cc4000' of type '__gtksharp_0_MyApp+2bMyCustomObj'
我可以用一只手,因为我没有想法。