1. 程式人生 > >WPF後臺動態呼叫樣式檔案,不用來回改App.g.cs

WPF後臺動態呼叫樣式檔案,不用來回改App.g.cs

應用場合:如果您的WPF應用程式設定WPF執行一個例項程式碼後,App.xaml檔案中對樣式資源字典檔案的引用將失效.

解決辦法1:在App.xaml.cs檔案中用反射動態呼叫另外一個DLL專案中的樣式檔案即可

詳細操作介紹如下:

1、WPF設定只執行一個例項程式碼:

App.xaml檔案程式碼如下:
    <Application.Resources>         
     <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
         <ResourceDictionary Source="ButtonStyle.xaml"/>
     </ResourceDictionary>         
    </Application.Resources>
</Application>

App.xaml.cs檔案程式碼如下:

//新增引用
using System.Diagnostics;
using System.IO;
using System.Reflection;

namespace WpfUI
{

    /// <summary>
    /// App.xaml 的互動邏輯
    /// </summary>
    public partial class App : Application
    {

        public App()
        {
        }

        /// <summary>
        /// 要設定App.xaml的檔案屬性中生成操作=無
        /// </summary>
        [STAThread]        
        public static void Main()
        {
            App myApp = new App();                          
            myApp.ShutdownMode = ShutdownMode.OnExplicitShutdown;
            myApp.Run();
        }

        private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            if (e.Exception is InvalidOperationException)
                e.Handled = true;
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            //獲取當前執行WPF程式的程序例項
            Process process = Process.GetCurrentProcess();
            //遍歷WPF程式的同名程序組
            foreach (Process p in Process.GetProcessesByName(process.ProcessName))
            {
                if (p.Id != process.Id && (p.StartTime - process.StartTime).TotalMilliseconds <= 0)
                {
                    p.Kill();//關閉程序
                    return;
                }
            }
            base.OnStartup(e);
            //啟動登陸窗體,

          MainWindow myWindow = new MainWindow();

          myWindow.Show();
      }

    }

}

2、ButtonStyle.xaml樣式檔案內容如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!--按鈕樣式-->
    <Style x:Key="RedButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="Foreground" Value="Red"/>
        <Setter Property="Background" Value="Silver"/>
        <Setter Property="Height" Value="23"/>
    </Style>
    
</ResourceDictionary> 

3、MainWindow.xaml檔案內容如下:

<Window x:Class="WpfUI.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Content="Button" Style="{StaticResource RedButtonStyle}" Height="23" HorizontalAlignment="Left" Margin="102,66,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
    </Grid>
</Window>
 

4、執行程式後發現按鈕樣式RedButtonStyle總提示找不到

5、 解決辦法如下:

第一步: 新建一個Windows--類庫專案WpfThems,將ButtonStyle.xaml拷貝過去, 設定ButtonStyle.xaml檔案的屬性生成操作為 "Page",之後生成WpfThems.dll檔案

第二步:在當前專案WpfUI中新增WpfThems專案引用

第三步:修改App.xaml.cs 檔案程式碼:新增一個函式LoadStyleResource並修改OnStartup函式內容。修改後的App.xaml.cs檔案內容如下:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
//新增引用
using System.Diagnostics;
using System.IO;
using System.Reflection;

namespace WpfUI
{
    /// <summary>
    /// App.xaml 的互動邏輯
    /// </summary>
    public partial class App : Application
    {

        public App()
        {
        }

        /// <summary>
        /// 設定WpfUI專案中的App.xaml的檔案屬性中"生成操作"為"無"
        /// 設定WpfThemes專案中的ButtonStyle.xaml的檔案屬性中"生成操作"為"Page"
        /// </summary>
        [STAThread]
        public static void Main()
        {
            App myApp = new App();
            myApp.ShutdownMode = ShutdownMode.OnExplicitShutdown;
            myApp.Run();
        }

        /// <summary>
        /// 過載應用程式啟動函式
        /// </summary>
        /// <param name="e"></param>
        protected override void OnStartup(StartupEventArgs e)
        {
            //獲取當前執行WPF程式的程序例項
            Process process = Process.GetCurrentProcess();
            //遍歷WPF程式的同名程序組
            foreach (Process p in Process.GetProcessesByName(process.ProcessName))
            {
                if (p.Id != process.Id && (p.StartTime - process.StartTime).TotalMilliseconds <= 0)
                {
                    p.Kill();//關閉程序
                    return;
                }
            }
            base.OnStartup(e);
            //動態呼叫樣式檔案
            LoadStyleResource();

            //啟動窗體
            MainWindow myWindow = new MainWindow();
            myWindow.Show();
        }
        private void LoadStyleResource()
        {
            Assembly assembly = Assembly.LoadFrom("WpfThemes.dll");
            string packUri = @"/WpfThemes;component/ButtonStyle.xaml";
            ResourceDictionary myResourceDictionary = Application.LoadComponent(new Uri(packUri, UriKind.Relative)) as ResourceDictionary;
            this.Resources.MergedDictionaries.Add(myResourceDictionary);
        }
    }
}

解決辦法2:在需要引用樣式的窗體的xaml檔案中新增對指定樣式檔案的引用

<Window.Resources>

 <ResourceDictionary>

<ResourceDictionary.MergedDictionaries>

<ResourceDictionary Source="ButtonStyle.xaml"/>

 </ResourceDictionary.MergedDictionaries>

 </ResourceDictionary>

</Window.Resources>