Dear fellow developers:
Metro and Office themes require code to load and initialize the theme resources... and we've gotten used to "blind design" with the base theme and having to run the app to actually see the themed windows and controls.
VS2015 has a new Xaml designer which (finally) has the ability to run code in designmode. For VS2013 and earlier you'll need a bit of extra code and two nuget packages from Fody to achieve the same...
First prep the code:
Public Class ThemeHelper Shared _IsInitialized As Boolean Shared Sub Initialize() If Not _IsInitialized Then ActiproSoftware.Windows.Themes.ThemeManager.BeginUpdate() 'Register Metro (requires reference to ActiproSoftware.Themes.Metro.Wpf) ActiproSoftware.Windows.Themes.ThemesMetroThemeCatalogRegistrar.Register() 'Register Office (requires reference to ActiproSoftware.Themes.Office.Wpf) ActiproSoftware.Windows.Themes.ThemesOfficeThemeCatalogRegistrar.Register() ActiproSoftware.Windows.Themes.ThemeManager.EndUpdate() _IsInitialized = True End If End Sub End Class
You can call this code in the constructor of your Application object, or if you're not running a WPF application call it in the constructor of the Control or Window you're designing. Just do it BEFORE InitializeComponents.
Class Application Public Sub New() ThemeHelper.Initialize() End Sub ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException ' can be handled in this file. End Class ' OR Class MainWindow Public Sub New() ThemeHelper.Initialize() ' This call is required by the designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. End Sub End Class
In your window or control's xaml: choose: but if you mix the runtime settings take precedence!
Mixing the above DesignMode and Runtime attached properties may not be the best idea.. the designer will show the runtime theme of MetroLight... in my experience it's best the set the DesignTimeTheme only... and leave the runtime theme to the global ThemeManager.
goto Tools/Options/Xaml Designer/General and check : "Run Project code in XAML designer (if supported)"
Now you will see your control in all it's themed glory right in the designer!
Note: You'll need to rebuild your project if you make changes to the xaml defined theme..
You'll need the nuget package manager extenstion.
Install Fody ( a package for weaving .Net assemblies)
Install Fody/ModuleInit (https://github.com/Fody/ModuleInit)
My packages.config looks like:
<?xml version="1.0" encoding="utf-8"?> <packages> <package id="Fody" version="1.29.3" targetFramework="net4" developmentDependency="true" /> <package id="ModuleInit.Fody" version="188.8.131.52" targetFramework="net46" developmentDependency="true" /> </packages>
Insert or update a file called FodyWeavers.xml: Mine looks like:
<?xml version="1.0" encoding="utf-8"?> <Weavers> <ModuleInit /> </Weavers>
ModuleInit will add a file called ModuleInitializer.cs to your vb project. Never mind: easily removed and replaced with the translated vb class.
I've dumped all required class in a single file called DesignTimeStuff.vb...
' This could be moved to AssemblyInfo <Assembly: DesignTimeCode(GetType(Initializer))> <HideModuleName> Module DesignModeHelper Function IsInDesignMode() As Boolean Return System.ComponentModel.DesignerProperties.GetIsInDesignMode(New DependencyObject) End Function End Module ''' <summary> ''' This code is called at designtime builds ''' </summary> ''' <remarks></remarks> Public Class Initializer Inherits DesignTimeInitializerBase Protected Overrides Sub Initialize() Application.InitializeThemes() End Sub End Class ''' <summary> ''' ModuleInitializer is required by ModuleInit.Fody (via FodyWeavers.xml) ''' </summary> ''' <remarks></remarks> Public NotInheritable Class ModuleInitializer Public Shared Sub Initialize() If IsInDesignMode() Then For Each assembly In AppDomain.CurrentDomain.GetAssemblies() Dim attributes = assembly.GetCustomAttributes(GetType(DesignTimeCodeAttribute), True) ' No need to do anything For Each attribute In attributes Next Next End If End Sub End Class ''' <summary> ''' Specifies a type(class) to be constructed during DesignTime ''' </summary> ''' <remarks></remarks> <AttributeUsage(AttributeTargets.Assembly, AllowMultiple:=True)> _ Public Class DesignTimeCodeAttribute Inherits Attribute Private Shared ReadOnly InitializedTypes As New Dictionary(Of Type, Boolean)() Public Sub New(typeToConstruct As Type) If InitializedTypes.ContainsKey(typeToConstruct) Then Return End If InitializedTypes(typeToConstruct) = True If IsInDesignMode() Then Activator.CreateInstance(typeToConstruct) End If End Sub End Class ''' <summary> ''' Represents the base class for implementing DesignTime Initializers ''' </summary> ''' <remarks></remarks> Public MustInherit Class DesignTimeInitializerBase Public Sub New() If CanInitialize Then Initialize() End If End Sub Public ReadOnly Property CanInitialize() As Boolean Get Return IsInDesignMode() End Get End Property Protected Overridable Sub Initialize() End Sub End Class
questions to email@example.com
[Modified 6 years ago]