web-dev-qa-db-ja.com

WPFクラスライブラリのアセンブリ全体/ルートレベルのスタイル

WPFをサポートするC#(2008/.NET 3.5)クラスライブラリアセンブリがあります( この記事 に基づく)。
いくつかのウィンドウを作成しましたが、現在、それらに共通のスタイルセットを作成しようとしています。ただし、これは(WPFアプリではなく)クラスライブラリであるため、グローバルアクセス用にこれらのスタイルを格納するapp.xaml(およびそれに含まれるApplicationと対応するApplication.Resources)がありません。

So:アセンブリ内のすべてのxamlファイルに表示されるスタイル定義のトップレベルセットを作成するにはどうすればよいですかapp.xamlがない場合(上記を参照)?および/または動作中のapp.xamlをクラスライブラリに追加することは可能ですか?

参考までに、ResourceDictionary.xamlファイルにResourceDictionaryを作成して、「Window.Resources」ブロック内の各ウィンドウに含めてみました。これは、ボタンなどのスタイリングを解決することが判明しましたが、囲んでいるウィンドウでは解決しませんでした。 Style="{StaticResource MyWindowStyle}"ウィンドウの開始ブロックで、コンパイルしてVSデザインウィンドウに正常に表示されますが、実際の実行時に解析例外が発生します(MyWindowStyleが見つかりませんでした。VisualStudioでは、行の後に辞書が含まれていると思います問題ですが、CRLはより順番に処理を行うため、ResourceDictionaryをまだロードしていません)。


アイデアに感謝しますが、それでもうまくいきません...どうやらクラスライブラリはgeneric.xamlの使用法を暗黙的にサポートしていません。クラスライブラリプロジェクトにgeneric.xamlを追加し、そのビルドアクションを「リソース」に設定しました。を含む:

<ResourceDictionary 
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Window}" x:Key="MyWindow">
        <Setter Property="Background" Value="Black"/>
    </Style>
</ResourceDictionary>

テーマを使用したいウィンドウxamlは次のようになります。

<Window x:Class="MyAssembly.ConfigureGenericButtons"
    x:ClassModifier="internal"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
    Style="{StaticResource MyWindow}"
    Title="ConfigureGenericButtons">
...Buttons, etc...
</Window>

VSデザインウィンドウには、MyWindowスタイル(つまり、黒い背景)を使用したウィンドウは表示されませんが、正常にコンパイルされて起動します。ただし、このクラスライブラリを含むアプリがこのウィンドウを表示する呼び出しを行うと、XamlParseExceptionが発生します。

'{MyWindow}'という名前のリソースが見つかりません。

また、ウィンドウがデフォルトでスタイルを使用するかどうかを確認するために、Styleパラメーターを省略してみました(そして、generic.xamlのx:Keyを含む場合と含まない場合の両方で試しました)。エラーはありませんが、generic.xamlで定義されているものも表示されませんでした。

私はここで何か間違ったことをしていますか、またはウィンドウで一般的なカスタムスタイルを使用できるようにする方法に関する他のアイデア(つまり、各ウィンドウのxamlでスタイルを定義する必要はありません)-これはそうではないという警告があります応用?

47
WarpedBoard

追加してみてください

Style={DynamicResource MyStyle}

この場合、StaticResourceを使用することはできません。

14
Jab

これはテーマの仕事のように聞こえます。

  1. _/themes/generic.xaml_ ResourceDictionaryをプロジェクトに追加します。
  2. 以下をAssemblyInfo.csに追加します:[Assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
  3. 利益!

ジェネリックに追加したリソースはすべて、すべてのコントロールで使用されます。また、themesディレクトリに正しいテーマ名のResourceDictionaryファイルを含めることで、プロファイル固有のテーマ(Luna、Aeroなど)を作成できます。

詳細情報へのリンクは次のとおりです。 カスタムテーマを作成して適用

13

App.xamlがない場合でも、アプリケーションレベルのリソースにロードできますが、これを行うには、次のようなコード(xamlではない)を作成する必要があります...

void LoadIt()
{
     ResourceDictionary MyResourceDictionary = new ResourceDictionary();
     MyResourceDictionary.Source = new Uri("MyResources.xaml", UriKind.Relative);
     App.Current.Resources.MergedDictionaries.Add(  MyResourceDictionary )
}

例については、このサイトをチェックしてください: http://ascendedguard.com/2007/08/one-of-Nice-features-about-wpf-is-how.html

3
Muad'Dib

Dr. WPF(または以前はDr. WPFとして知られていた人)は、この件に関して素晴らしい 投稿 を持っています。

これは、彼らがApplicationオブジェクトを作成し、リソースを追加する投稿からの抜粋です。

if (Application.Current == null)
{
    // create the Application object
    new Application();

    // merge in your application resources
    Application.Current.Resources.MergedDictionaries.Add(
        Application.LoadComponent(
            new Uri("MyLibrary;component/Resources/MyResourceDictionary.xaml",
            UriKind.Relative)) as ResourceDictionary);
}

私のアセンブリは相互運用機能を介してホストされているため、ShutdownModeの設定を次のように追加し、終了したらシャットダウンする必要がありました。

new Application() { ShutdownMode = ShutdownMode.OnExplicitShutdown };

それは魅力のように機能しました。

1
KornMuffin

window.Resourceにロードすると、ディクショナリはそのウィンドウの子のみが使用できます。ウィンドウとその子が使用できるようにする必要があります。

App.xamlファイルにロードしてみてください。これにより、ウィンドウレベルのリソースではなく、アプリケーションレベルのリソースになります。

0
Muad'Dib

それで、多くの時間を費やした後、私はついにこれを理解しました。方法は次のとおりです。

  1. WPFコントロールライブラリで、themesという名前の新しいフォルダーを追加します。
  2. themesフォルダー内に、generic.xamlという名前のリソースディクショナリを追加します。
  3. generic.xaml内に、次の構文を使用してリソースを追加します。

    <SolidColorBrush x:Key="{ComponentResourceKey {x:Type local:UserControl1}, MyEllipseBrush}" Color="Blue" />
    
  4. コントロールで、次の構文を使用してこのリソースにアクセスします。

    Background="{StaticResource {ComponentResourceKey {x:Type local:UserControl1}, MyEllipseBrush}}"
    

注意事項:

  1. 手順1と2は通常、新しいWPFコントロールライブラリを作成するときにVisualStudioによって自動的に実行されます。
  2. ComponentResourceKeyの最初のパラメーターの目的を完全には理解していませんが、必須です。このリソースを消費するコントロールの名前を使用します。
  3. 私の場合、VisualStudioのデザイナーはリソースを見つけることができませんでした。キャッシュの問題である可能性がありますが、よくわかりません。ただし、実行時には問題なく動作します。
  4. この構文の詳細については、 このMSDNの記事 を参照してください。

これがいくつかの生活を楽にしてくれることを願っています。

0
dotNET