Notebook中EventBox与其派生类的行为差异问题
GTK# 派生EventBox与原生控件背景不一致的问题
我之前一直笃定:如果一个派生类完全直接继承自基类、没做任何重写或自定义逻辑,那它的行为肯定和基类完全一致。但最近在GTK#里用EventBox组件时,发现了一个打破这个认知的反例:当开启VisibleWindow属性后,放在Notebook内、处于StateType.Normal状态的原生EventBox,和我自定义的纯继承EventBox的派生控件,背景表现居然不一样!
复现代码(已修复)
以下是能直接编译运行的测试代码,可复现该差异:
using Gtk; using System; public class TestWindow : Window { public TestWindow() : base("EventBox Inheritance Test") { SetDefaultSize(400, 300); DeleteEvent += (s, e) => Application.Quit(); var notebook = new Notebook(); Add(notebook); // 原生EventBox控件 var nativeBox = new EventBox(); nativeBox.VisibleWindow = true; nativeBox.Add(new Label("Native EventBox (Normal State)")); notebook.AppendPage(nativeBox, new Label("Native")); // 完全继承自EventBox的自定义控件(无任何修改) var customBox = new CustomEventBox(); customBox.VisibleWindow = true; customBox.Add(new Label("Custom Derived EventBox (Normal State)")); notebook.AppendPage(customBox, new Label("Custom Derived")); ShowAll(); } // 无任何自定义逻辑的派生类 public class CustomEventBox : EventBox { public CustomEventBox() : base() { } } public static void Main(string[] args) { Application.Init(); new TestWindow(); Application.Run(); } }
现象说明
运行后你会发现:原生EventBox的背景和Notebook页面背景完全融合,但自定义派生的EventBox却会显示出不同的背景样式(比如带有控件默认的浅底色),哪怕两者的VisibleWindow都设为true,且都处于StateType.Normal状态。
原因与解决办法
这个问题的根源在于GTK的CSS样式系统:GTK是通过控件的CSS类名来匹配样式规则的。原生EventBox会自动带有eventbox这个CSS类,所以能应用系统定义的EventBox样式;但自定义派生类默认只会添加和类名一致的CSS类(比如这里的CustomEventBox),不会自动继承基类的eventbox类,因此无法匹配到原生EventBox的样式规则。
解决办法很简单,只需要在派生类的构造函数里手动添加基类的CSS类即可:
public class CustomEventBox : EventBox { public CustomEventBox() : base() { // 添加基类的CSS类,让样式系统识别它属于EventBox StyleContext.AddClass("eventbox"); } }
添加之后,自定义派生控件的样式就会和原生EventBox完全一致了。
内容的提问来源于stack exchange,提问作者JiffyJuff
相关产品推荐
相关产品推荐

