8

私はwpfテーマと少し混乱しています。Vista、Windows 7、および Windows 8 で wpf 画面を同じように表示したいので、それに応じてコンポーネントのスタイルを設定し、Windows 8 で実行する場合を除いて問題を引き起こしません。たとえば、コンボボックスがあり、このようにxamlでデフォルトの背景を変更します。

<Style TargetType="{x:Type ComboBox}" >
    <Setter Property="FontStyle" Value="Normal"/>
    <Setter Property="Height" Value="24" />
    <Setter Property="Background" Value="{StaticResource GradientButtonBackgroundBrush}"/>
</Style>

コンボボックスの Background プロパティは Windows 8 では効果がなく、右に矢印が付いた平らな四角形しか得られません (デフォルトの Windows 8 コンボボックスで、設計が不十分です!)。

だから、私の質問は、コンボボックスをすべてのバージョンのウィンドウで同じように見せるにはどうすればよいかということです。以下のように App.xaml に Windows Aero テーマを追加しようとしましたが、コンボボックスの表示には影響しません。Aeroテーマを追加した方法は次のとおりです

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/PresentationFramework.Aero;component/themes/aero.normalcolor.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>

テーマに関しては、別の疑問もあります。私は、デフォルトで(私が信じている)Aeroテーマが設定されているWindows 7マシンでwpfアプリケーションを構築しています。したがって、Windows 7 マシンで表示した場合、すべてのスタイルは Aero テーマに基づいています。XP などでアプリケーションを実行するとどうなりますか。次に、上記のコードにリストされているように、App.xaml にリソース ディクショナリ (Aero テーマ) のエントリを追加する必要がありますか?

私の質問が少し漠然としていることは承知していますが、私を信じてください。さまざまな Windows バージョンの wpf のデフォルトのテーマと本当に混乱しています。

編集: 必要に応じてコンボボックスをスタイルすることはまだできません。コンボボックスは依然として灰色の長方形のように見えます。

これが私がしたことです。Microsoft のサイトから Aero.NormalColor.xaml をダウンロードし、アプリケーションのテーマ フォルダーに含めました。次に、App.xamlに次を追加しました

    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Themes/Aero.NormalColor.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>

次に、アプリケーションをコンパイルし、Windows 8 に展開しました。以前に示したものと同じコンボボックスです。他のすべての要素は、テーマに従って適切にスタイル設定されることに注意してください。Luna.Metallic.xaml でも同じことを行い、ComboBoxを除くすべての要素がスタイル設定されます。

ControlTemplateでスタイルを定義する特定のテーマをロードすると、wpf で選択する必要があると思います。Aero (または Luna) コントロール テンプレートを指定した後でもComboBoxだけがその外観を変更しない理由について、私は混乱しています。何か案は ?

EDIT-2 Windows 8 でのコンボボックスの表示のスクリーン ショット ここに画像の説明を入力

4

5 に答える 5

1

組み込みのテンプレートを少しハックしました。最もクリーンなソリューションではありませんが、独自のテンプレートを展開する必要があるという頭痛の種が解消されます。コード ビハインドは基本的に、組み込みのテンプレート ボーダーのプロパティをコンボ ボックスのプロパティにバインドします。

<Style TargetType="ComboBox">
    <Setter Property="Border.Background" Value="White"/>
    <EventSetter Event="Loaded" Handler="ComboBox_Loaded"/>
    <Style.Triggers>
        <Trigger Property="IsReadOnly" Value="True">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
        </Trigger>
        <Trigger Property="IsFocused" Value="True">
            <Setter Property="Background" Value="{StaticResource ResourceKey=FocusedControlBackcolorBrush}"/>
            <Setter Property="BorderBrush" Value="{StaticResource ResourceKey=FocusedControlBorderBrush}"/>
        </Trigger>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="BorderBrush" Value="{StaticResource ResourceKey=FocusedControlBorderBrush}"/>
        </Trigger>
    </Style.Triggers>
</Style>


    private void ComboBox_Loaded(object sender, RoutedEventArgs e)
    {
        var comboBox = sender as ComboBox;
        var toggleButton = comboBox.Template?.FindName("toggleButton", comboBox) as ToggleButton;
        var border = toggleButton?.Template.FindName("templateRoot", toggleButton) as Border;
        if (border != null)
        {
            Binding b = new Binding("Background");
            b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ComboBox), 1);
            BindingOperations.SetBinding(border, Control.BackgroundProperty, b);

            b = new Binding("BorderBrush");
            b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ComboBox), 1);
            BindingOperations.SetBinding(border, Control.BorderBrushProperty, b);
        }
    }
于 2014-10-14T03:17:02.500 に答える
0

@Viv への返信

@Viv、あなたの答えは非常に明確だったと思いますが、どういうわけかあなたの意見/提案は私には消化できません。その理由を簡単に説明します

あなたの提案

さまざまな OS バージョン間でスタイルを持ちたい場合 (新しいバージョンがオーバーライドを台無しにしていないかどうかバックトラックしてチェックし続ける必要はありません)、簡単なルールは自分で作成することです。

実用的ではないようです。テーマのまさにその考え方は、アプリケーション内のすべての要素とすべてのプラットフォームにわたって一貫した外観を作成することです。したがって、フレームワークによって提供される特定のテーマを使用する場合、少なくとも現在の主要なプラットフォームでは、満足のいくレベルの一貫性を達成できるはずです。とりわけ、誰もがすべてのスタイルとテンプレートをゼロから作成する専門知識を持っているわけではありません。テーマのコンセプトは、

「フレームワーク プロバイダーは、通常のシナリオで適切に機能するテーマを提供しており、自分のテーマを展開したい人は歓迎します」 .

代わりに、ここのコンセプトは次のようです

「フレームワーク プロバイダーはテーマを提供しています。一貫性があり、壊れることなく動作することは保証されていません。そのため、常にテーマを展開してください」

あなたの見積もり

上からわかるように、使用されている背景は {TemplateBinding Background} ではなく {StaticResource ComboBox.Static.Background} です。したがって、その ComboBox に対して Windows-8 で Background プロパティを設定しても効果が見られない理由

そのようなテンプレートを作成するのが誰のアイデアだったのかわかりません! 彼の気が狂っているに違いないか、私が愚かすぎて利点を理解できません。アプリケーションで青色のテーマを使用していて、明日、Windows 9 で誰かが赤色{StaticResource ComboBox.Static.Background}として定義していると想像してみてください。それで、私は今、すべての要素が「青」をテーマにしており、コンボボックスのみが「赤」に見える派手なウィンドウ画面を持っていると思います。つまり、テーマのアイデアそのものがここで壊れています!

あなたの補足

たとえば、あなたは Windows-8 スタイルは好きではない、と言いましたが、私は反対です。私は実際、Windows 8 のクリーンでシンプルな外観が気に入っています。

私のコンボボックスは無効なボタンのように見え、背景を変更することさえできませんでした! ボタンはクリックできるようには見えません! あなたが言ったように、これはもちろん個人的な選択です。

私の結論 Windows 8でコンボボックスを機能させる方法について何か提案があれば、しばらく待ちます。あなたの答えは真実をもたらします。解決。

ニルヴァン

于 2013-04-24T11:32:40.923 に答える
0

新しいテンプレートには、背景スタイルを尊重しないハードコードされた背景色を持つ Grid->ToggleButton->Border があります。@Matstar からの回答に基づいて、背景色を同期する方法を作成しました。

バインディングを背景色に設定することもできます。コードはこれを取得し、必要に応じて再適用します。

<ComboBox ItemsSource="{Binding Values}" x:Name="Cbo2"
Background="{Binding Path=SelectedValueBgColor}" ... />

次に、xaml.cs で

cbo.Loaded += (sender, args) =>
{
    var comboBox = sender as ComboBox;
    if (comboBox != null)
    {
        var toggleButton = comboBox.Template?.FindName("toggleButton", comboBox) as ToggleButton;
        var border = toggleButton?.Template.FindName("templateRoot", toggleButton) as Border;
        if (border != null)
        {
            var existing = BindingOperations.GetBinding(comboBox, BackgroundProperty);
            BindingOperations.SetBinding(border, BackgroundProperty, existing);
        }
    }
};

バックグラウンドバインディングがnullを返さないことを確認してください

意味のある値がない場合は、透明または白またはその他のデフォルトを返します。null を返す背景にバインドすると、コンボボックスは機能しなくなります。

イベントが発生したときに更新が必要な場合は、バックグラウンド バインディングで変更されたプロパティを必ず通知してください。

于 2016-01-27T02:12:14.830 に答える