从捆绑包运行和从Xamarin Studio运行时,GTK UI看起来不同

时间:2015-11-01 10:07:14

标签: c# xamarin mono gtk gtk#

我有使用Mono框架的C#App和用于UI的GTK。当我从Xamarin Studio运行时,它看起来像这样

enter image description here

我已经将Mono和GTK捆绑到一个独立的软件包中。当它从它运行时它看起来不同。

enter image description here

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

1 个答案:

答案 0 :(得分:2)

GTK 2主题选项:

  • 使用默认系统主题
  • 每位用户通过~/.gtkrc
  • 主题
  • 每次申请通过GTK api
  • 通过环境var
  • 进行应用

GTK 2主题:

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

Mono w / 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”)的一个

至于控制哪个主题应用于您的应用程序,您可以允许用户通过基于$ HOME目录的.gtkrc文件来控制它(恕我直言:有多少用户真的知道如何做到这一点,或者甚至会并且“专家”最终用户调整用户界面的支持噩梦,我更喜欢将UIX体验锁定到所有用户统一的东西,但是,这只是我的选择。

您应该能够在应用启动脚本中设置环境var 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}); 

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

对于独立的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); 
        }

    }
}