65

app.xaml で、WPF Windows アプリケーションのすべてのウィンドウに既定のスタイルを設定しようとしています。これまでのところ、app.xamlにこれがあります:

<Application.Resources>
    <ResourceDictionary>
        <Style x:Key="WindowStyle" TargetType="{x:Type Window}">
            <Setter Property="Background" Value="Blue" />
        </Style>
    </ResourceDictionary>
</Application.Resources>

次の方法で、このスタイルを使用するようにウィンドウに具体的に指示することで、アプリの実行時に (VS デザイナーではなく) このスタイルでウィンドウを表示できます。

Style="{DynamicResource WindowStyle}

これは機能しますが、理想的ではありません。では、どうすればよいですか:

  1. すべてのウィンドウが自動的にスタイルを使用するようにします (すべてのウィンドウで指定する必要はありません)。
  2. VSデザイナーにスタイルを見せてもらいますか?

ありがとう!

4

8 に答える 8

49

レイの言葉に付け加えると:

スタイルについては、キー/ID を指定するか、TargetType を指定する必要があります。

FrameworkElement が明示的に指定された Style を持たない場合、独自の型をキーとして使用して常に Style リソースを探します
- Programming WPF (Sells, Griffith)

TargetType を指定すると、そのタイプのすべてのインスタンスにスタイルが適用されます。ただし、派生型はそうではありません...そうです。<Style TargetType="{x:Type Window}">すべてのカスタム派生/ウィンドウでは機能しません。<Style TargetType="{x:Type local:MyWindow}">MyWindow のみに適用されます。したがって、オプションは

  • スタイルを適用するすべてのウィンドウの Style プロパティとして指定する Keyed Style を使用します。デザイナーは、スタイル付きのウィンドウを表示します。

.

    <Application.Resources>
        <Style x:Key="MyWindowStyle">
            <Setter Property="Control.Background" Value="PaleGreen"/>
            <Setter Property="Window.Title" Value="Styled Window"/>
        </Style>
    </Application.Resources> ...
    <Window x:Class="MyNS.MyWindow" Style="{StaticResource MyWindowStyleKey}">  ...
  • または、Ctor/Initialization/Load ステージで一度 Style プロパティを設定するカスタム BaseWindow クラス (独自の癖があります) から派生させることもできます。その後、すべての派生に自動的にスタイルが適用されます。しかし、デザイナーはあなたのスタイルに気付かないスタイルが適用されていることを確認するには、アプリを実行する必要があります.デザイナーは InitializeComponent (自動/デザイナー生成コード) を実行するだけなので、XAML は適用されますが、カスタムではありませんコードビハインド。

したがって、明示的に指定されたスタイルは最小限の作業であると言えます。とにかく、スタイルの側面を一元的に変更できます。

于 2009-01-20T10:34:40.133 に答える
24

これは数年後のことですが、質問はまだここにあるので...

  1. プロジェクトにリソースディクショナリを作成します(プロジェクトを右クリックします...)

    プロジェクトの下に「Assets」という名前の新しいフォルダーを作成し、その中に「resourceDict.XAML」を配置します。

  2. コードをresourceDict.XAMLに追加します。

    <Style x:Key="WindowStyle" Target Type="Window" >
         <Setter Property="Background" Value="Blue" />
    </Style>
    
  3. プロジェクトXAMLファイルで、ウィンドウの下に以下を追加します。

    <Window.Resources>
        <ResourceDictionary>
            <!-- Believe it or not the next line fixes a bug MS acknowledges -->
            <Style TargetType="{x:Type Rectangle}" />
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Assets/resourceDict.XAML" />
            </ResourceDictionary.MergedDictionaries>
        <ResourceDictionary>
    </Window.Resources>
    

    次のWebサイトを参照してください。マージされたディクショナリを含むリソースディクショナリを参照する際の問題 「バグがあります。すべてのデフォルトスタイルがマージされたディクショナリにネストされている場合、3レベル(またはそれ以上)の最上位ディクショナリにフラグが付けられないため、検索がスキップされます。回避策は、ルートディクショナリの何かにデフォルトのスタイルを設定することです。」そして、それは物事を確実に修正するようです。図に行く...

  4. そして最後に、ウィンドウの下で、おそらくタイトルの後、最後のウィンドウの前'>':

    Style="{DynamicResource windowStyle}"
    
  5. また、スタイルを適用するすべてのプロジェクトに、手順3と4のコードを追加する必要があります。

  6. 単色ではなくグラデーションの背景を使用する場合は、resourceDict.XAMLに次のコードを追加します。

    <LinearGradientBrush x:Key="windowGradientBackground" StartPoint="0,0"
            EndPoint="0,1" >
    <GradientStop Color= "AliceBlue" Offset="0" />
    <GradientStop Color= "Blue" Offset=".75" />
    </LinearGradientBrush>
    
  7. そして、背景色が読み取れるようにスタイルセッターを変更します。

    <Setter Property="Background" Value="{DynamicResource
            windowGradientBackground}" />
    

上記のように、各project.XAMLファイルで手順3と4を繰り返す必要がありますが、ソリューション全体で統一されたWindowsが得られます。また、同じプロセスを、均一な外観にしたいコントロール、ボタンなどにも適用できます。

これが遅くなる人にとっては、元のポスターが何年も前にこれをすべて理解したと確信しているので、これが役立つことを願っています。

ポール

于 2012-03-27T21:11:41.867 に答える
8

DynamicResource を指定しているため、デザイナーが機能していません。これを StaticResource に変更してください。すべて問題ありません。

すべてのウィンドウに適用するには、スタイルから x:Key を削除する必要があります。TargetType を設定すると、暗黙的に x:Key が TargetType にあるものに設定されます。ただし、私のテストでは、これは機能していないため、調査中です。

TargetType を x:Type TextBlock に設定すると、デザイナーは完全に機能します。異なる動作を示しているのはウィンドウのようです。

于 2009-01-10T23:23:18.553 に答える
7

このコードを App.xaml.cs ファイルに追加できます。

        FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata
        {
            DefaultValue = Application.Current.FindResource(typeof(Window))
        });

この後、型に適用されたスタイルは、Windowから派生したすべての型にも適用されます。Window

于 2017-01-31T15:15:23.447 に答える
1

この問題の解決策に苦労している人のために: カスタム スタイルをすべての Window 派生型に自動的に適用するにはどうすればよいですか? 以下は私が思いついた解決策です

注: Window タイプから派生させたり、各ウィンドウに XAML を挿入してスタイルの更新を強制したりする必要はありませんでした。これは、私のプロジェクトに固有の理由によるものです (私の製品の消費者は、私の一般的な再利用可能なスタイル ライブラリを使用し、独自のスタイル ライブラリを作成します)。レイアウト/ウィンドウなど) だから、どんな副作用があっても喜んで生きていける、うまくいく解決策を見つけることに本当にやる気がありました

インスタンス化されたすべてのウィンドウを繰り返し処理し、ウィンドウ タイプに対して定義した新しいカスタム スタイルを強制的に使用する必要があります。これは、すでに起動しているウィンドウにはうまく機能しますが、ウィンドウまたは子ウィンドウがインスタンス化されると、その基本型に対して宣言された新しい/カスタム型を使用することを認識しません。バニラ ウィンドウ タイプ。したがって、私が思いついた最善の方法は、MainWindow で LostKeyBoardFocus を使用して、ChildWindow へのフォーカスを失ったとき (子ウィンドウが作成されたときの IOW)、この FixupWindowDerivedTypes() を呼び出すことでした。

何らかの種類のウィンドウ派生型がインスタンス化されたときに「検出」するためのより良い解決策があり、FixupWindowDerivedTypes() を呼び出すと、それは素晴らしいことです。この領域でも WM_WINDOWPOSCHANGING を処理すると便利なことがあります。

したがって、このソリューションは言うまでもなくエレガントではありませんが、ウィンドウに関連するコードや XAML に触れることなく仕事を完了できます。

   public static void FixupWindowDerivedTypes()
    {
        foreach (Window window in Application.Current.Windows)
        {
           //May look strange but kindly inform each of your window derived types to actually use the default style for the window type

                    window.SetResourceReference(FrameworkElement.StyleProperty, DefaultStyleKeyRetriever.GetDefaultStyleKey(window));
                }
            }
        }
    }


//Great little post here from Jafa to retrieve a protected property like DefaultStyleKey without using reflection.
http://themechanicalbride.blogspot.com/2008/11/protected-dependency-properties-are-not.html

//Helper class to retrieve a protected property so we can set it
internal class DefaultStyleKeyRetriever : Control
{
    /// <summary>
    /// This method retrieves the default style key of a control.
    /// </summary>
    /// <param name="control">The control to retrieve the default style key 
    /// from.</param>
    /// <returns>The default style key of the control.</returns>
    public static object GetDefaultStyleKey(Control control)
    {
        return control.GetValue(Control.DefaultStyleKeyProperty);
    }
}
于 2013-05-10T17:06:10.887 に答える
0

Gishuの回答を考慮して、もう 1 つの回避策を考え出しました。でもちょっと変かも。MVVM パターンを使用すると、ウィンドウのコード ビハインドと XAML ファイルの x:Class マークアップを削除できます。したがって、ウィンドウまたはカスタム ウィンドウのインスタンスは取得されますが、「ウィンドウ」クラスから派生し、部分的としてマークされた「MainWindow」クラスのインスタンスは取得されません。私はVSのようなウィンドウを作っているので、ウィンドウクラスを継承して機能を拡張する必要がありました。その場合、新しいウィンドウ クラスをパーシャルとして作成して、継承なしでコード ビハインドを作成できるようにすることができます。

于 2014-02-02T09:32:58.650 に答える