GTK UI 当 运行 来自 bundle 和 运行 来自 Xamarin Studio 时看起来不同

GTK UI Looks different when running from bundle and when running from Xamarin Studio

我有使用 Mono 框架和 GTK 的 C# 应用 UI.When 我 运行 它来自 Xamarin Studio 它看起来像这样

我已经将 Mono 和 GTK 捆绑到一个独立的 bundle.When 运行从它看起来不一样了。

哪个看起来更适合 OSX 平台?如果它是第一个,那么我怎样才能在捆绑的应用程序中获得相同的外观和感觉。

GTK 2 主题选项:

  • 使用默认系统主题
  • 每个用户主题通过 ~/.gtkrc
  • 每个应用程序通过 GTK 设置主题api
  • 通过环境变量为每个应用程序设置主题

GTK 2 主题:

在 GTK 2 中,主题是通过资源文件处理的,主文件通常名为 'gtkrc'。这些资源文件可以是独立的,包括其他资源文件和参考外部图像(图标)等。基于 gtkrc 的文件的内部结构超出了这里的范围,但是有很多参考资料GTK 2.0 的网络 resources/theming。

带有 GTK 2 的单声道:

OS-X 上的 Mono 安装默认的 GTK2 主题(gtkrc)和一些替代主题:

位置:/Library/Frameworks/Mono.framework/Versions/4.2.1

find . -name "gtkrc"
./etc/gtk-2.0/gtkrc
./share/themes/bubble/gtk-2.0/gtkrc
./share/themes/Clearlooks/gtk-2.0/gtkrc
./share/themes/Mac/gtk-2.0-key/gtkrc
./share/themes/Quartz/gtk-2.0/gtkrc
./share/themes/Xamarin/gtk-2.0/gtkrc

位于 <Mono/Version>/etc/gtk-2.0 中的那个是默认的(Tango 风格),而备选之一是 'Xamarin' 并且是用于风格化 Xamarin Studio 的那个(内部命名为 "Mac Theme for Xamarian").

至于控制将哪个主题应用到您的应用程序,您可以允许用户通过基于 .gtkrc 文件的 $HOME 目录来控制它(恕我直言:有多少用户真正知道该怎么做,甚至会'expert' 最终用户调整 UI 的目的和支持噩梦,我更喜欢将 UIX 体验锁定为对所有用户都统一的东西,但是,这只是我的选择).

您应该能够在您的应用程序启动脚本中设置环境变量 GTK2_RC_FILES,但我从来没有成功过。

注意:环境。变种。 GTK_THEME 在 GTK3 中工作(但 Mono 是 GTK2 绑定的)

通过 GTK 设置应用程序主题 api:

对于您的应用程序,您可以指定 GTK 使用 Mono 安装的主题之一或您的应用程序提供的主题。

BEFORE Gtk.Application.Init() 您可以执行以下操作来分配 gtkrc 文件:

Gtk.Rc.AddDefaultFile ({gtkrcFile}); 
Gtk.Rc.Parse ({gtkrcFile}); 

如果您有自己的主题,请将文件(gtkrc、其他包含的 gtkrc 文件、图标、图像等)捆绑在您的 .app 中。通常这些会被捆绑在你的包中的 Contents\Resource directory and use the above code to assign thegtkrc` 中。

对于独立的 exe,我还使用了一个嵌入式 gtkrc 文件并将其解压缩到一个运行时的 tmp 文件中:

using System;
using System.Reflection;
using System.IO;
using Gtk;

namespace themes
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            InitGlobalResourceFile ();
            Application.Init ();
            MainWindow win = new MainWindow ();
            win.Show ();
            Application.Run ();
        }

        static void InitGlobalResourceFile ()
        { 
            String gtkResouceFile;

            Assembly myAssembly = Assembly.GetExecutingAssembly ();
            string[] names = myAssembly.GetManifestResourceNames ();
            foreach (string name in names) {
                Console.WriteLine (name);
                if (name.Contains ("GtkThemeResource.rc")) {
                    gtkResouceFile = name;
                    break;
                }
                Console.WriteLine ("Gtk Theme Resource not found in manifest");
            }

            var tmpFile = Path.GetTempFileName ();
            var stream = myAssembly.GetManifestResourceStream (gtkResouceFile);
            string gtkrc;
            using (StreamReader reader = new StreamReader (stream)) {
                gtkrc = reader.ReadToEnd ();
            }
            using (StreamWriter outputFile = new StreamWriter (tmpFile)) {
                outputFile.WriteLine (gtkrc);
            }
            Rc.AddDefaultFile (tmpFile); 
            Rc.Parse (tmpFile); 
        }

    }
}