2

テーマを実装する必要がある非常に大きな Silverlight 5 アプリケーションを使用しています。残念ながら、C1 (Component One) または Silverlight Toolkit のテーマ メカニズムは使用できません。これは、xaml が膨大であり、コードを変更する必要があるためです。私は箱から出して何かをすることを余儀なくされています。

出発点として、 @Scott Whitlock によって書かれた Stack Overflow Using Mef to Import a WPF DataTemplateに関する投稿を参照して、デモ プロジェクトを作成しました。App.Current.Resources.MergedDictionariesこの投稿では、Silverlight/WPF リソース ディクショナリを動的に読み込み、Silverlight /WPF アプリケーション内のコレクションに追加する方法について説明しました。

4 つのプロジェクトを作成しました。1 つ目は Silverlight 5 アプリケーション自体で、2 つ目、3 つ目、4 つ目はすべてのテーマの詳細を定義するための Silverlight クラス ライブラリです。各クラス ライブラリには、 の派生型であるエントリ ポイントがありResourceDictionaryます。

AppStart イベントで、アプリケーションは既定のテーマ クラス ライブラリを読み込みます。これは基本的に、すべての既定のスタイルが Silverlight で定義された白紙の状態です。ロードとはDefaultTheme、クラス ライブラリ内で定義されたリソース ディクショナリがApp.Current.Resources.MergedDictionariesコレクションに追加されることを意味します。

ユーザーがアプリ内のコンボ ボックスから別のテーマを選択すると、コードは既存の既定のテーマを削除し、青または赤、またはその他のテーマのエントリ ポイント リソース ディクショナリをApp.Current.Resources.MergedDictionariesコレクションに追加します。

ただし、このアクションが発生したときにエラーがスローされていなくても、スタイル自体が再適用されることはありません。各テーマのスタイル キーが全体的に同じであることを確認しました。

App.Current.RootVisual「テーマの切り替え」後に、新しく追加されたリソース ディクショナリからスタイルを強制的に再適用する方法についてのアイデアはありますか?

ありがとう、

4

1 に答える 1

0

新しい ResourceDictionary を追加する前に、最初に現在の ResourceDictionary を検索して削除してみてください。

string themeName = "White";
string oldThemeName = "Black";
string oldResourcePathString = String.Format("/Library.Name;component/Themes/{0}Theme.xaml", oldThemeName);
StreamResourceInfo sriOldTheme = Application.GetResourceStream(new Uri(oldResourcePathString, UriKind.Relative));

if (sriOldTheme != null)
{
  StreamReader sr = new StreamReader(sriOldTheme.Stream);
  object resourceObject = XamlReader.Load(sr.ReadToEnd());

  ResourceDictionary resource = resourceObject as ResourceDictionary;
  if (resource != null)
  {
    Application.Current.Resources.MergedDictionaries.Remove(resource);
  }
}

string resourcePathString = String.Format("/Library.Name;component/Themes/{0}Theme.xaml", themeName);
StreamResourceInfo sriTheme = Application.GetResourceStream(new Uri(resourcePathString, UriKind.Relative));

if (sriTheme != null)
{
  StreamReader sr = new StreamReader(sriTheme.Stream);
  object resourceObject = XamlReader.Load(sr.ReadToEnd());

  ResourceDictionary resource = resourceObject as ResourceDictionary;
  if (resource != null)
  {
    Application.Current.Resources.MergedDictionaries.Add(resource);
  }
}

私はコードをテストしたことがないので、タイプミスをチェックしてください。ただし、App.xaml で ResourceDictionary を設定するか、MainPage.xaml.cs からプログラムで設定するかに関係なく、これは機能するはずです。

于 2014-07-30T18:28:02.943 に答える