web-dev-qa-db-ja.com

WPFアプリケーションがWindows 7とWindows 8で異なるように見えるのはなぜですか?これは修正できますか?

この質問がまだ聞かれていないように見えることに本当に驚いています...もしそうだとしたら、おfindびします。

私の仕事用コンピューターはWindows 7からWindows 8にアップグレードされたばかりです。私の恐ろしいことに、私のWPFアプリケーションはいくつかの点で異なって見えます。以下に例を示します。

Windows 7:

enter image description here

ウィンドウズ8:

enter image description here

Windows 8の問題(この画像からのみ):

  • ボタンを含む間違ったタイトルバー(最小、閉じるなど)
  • タイトルバーの間違ったサイズのフォント
  • 見出しの誤ったFontWeight(Windows 7のセミボールド設定= Windows 8のボールド設定)
  • タイトルバーのアイコン(またはテキスト)の位置がずれている
  • タイトルバーのアイコンはvery blurryです
  • 間違ったパディングおよび/またはマージン設定が左側のアイテムの間隔を空けています
  • 間違ったパディングおよび/またはマージン設定は、右側のテキストボックスの高さを減らします
  • 左のアイテムの「非表示」のデフォルト選択色は非表示ではなくなりました
  • 前に戻るチェックボックスのチェック
  • 一部のボタンの画像が非常にぼやけている

だから、私の質問はこれです:

WPFアプリケーションがWindows 7とWindows 8で異なるように見えるのはなぜですか?

これを明確にするために、私はnotの2つのオペレーティングシステムのWPFの違いのリストの後です。私もnot上記の個々のポイントの修正後です。誰かに説明してほしいwhyこれらのUIは異なって見える。これらの違いの原因は何ですか。また、PCでアプリケーションをレンダリングできるようにするWPFのシステム設定についての話を聞いたこともありますWindows 7の場合のようにですが、それがどれほど真実かはわかりません。


更新>>>

@AndrasSeböが親切に指摘したように、 WPFのWindows 7テーマ? というStackOverflowの質問があります。これはWindows XPの同様の問題を修正します。残念ながら、Windows 8には何の効果もないようです。実際にこの問題を引き起こすために実装された違いを知っているMicrosoftユーザーはいますか?それとも誰か?


更新2 >>>

わかりましたので、さらにテストを重ねた結果、この問題はnotがWindowsテーマに関連していると考え始めています。 @Gusdorの回答で提供されたコードを使用して、テーマをAeroに変更しようとしましたが、目に見える違いはありませんでした...次に、そのコードをテストするためにLunaに変更し、機能しました。

「機能」とは、Windowsテーマが変更されたことを意味しますが、UIコントロール、またはより正確には、不正なPaddingおよびMarginが残りました。その後、@AndrasSeböが言及したXAMLメソッドを使用してテーマをLunaに変更しようとしましたが、同じことが起こりました... ScrollBarsが異なって見えたため、テーマが変更されたことがわかりましたが、問題は残った。

だから今、私はこれが私が取り組んでいる真新しいコンピューターであるという事実と関係があるかもしれないと考えています...インストールする必要があるdllまたは設定があるかもしれませんか?私は本当にここで推測しているだけです-Windows 8.1を使用しているため、Microsoft .NET Framework全体をバージョン4.5.1にインストールしています。

この大規模なアプリケーションのすべてのビューを修正する時間がないため、これは絶対的な悪夢です。可能であれば助けてください。

20
Sheridan

残念ながら、この問題の簡単な修正方法はありませんでした。あなたが同様の状況にあり、ここで提供された答えがあなたのためにも機能しない場合、Windows 8のUIをWindowsのUIと同じように表示するために手動で行う必要がある変更の概要を次に示します7。

TextBoxPaddingをデフォルトに追加する必要がありますStyle

<Setter Property="Padding" Value="1.5,2" />

ListBoxItem:選択を隠し、背景色の上にマウスを置くには、新しいControlTemplateを提供する必要があります。

<Style x:Key="DefaultListBoxItem" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Padding" Value="0" />
    <Setter Property="Margin" Value="2,0,1,0" />
    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    <Setter Property="VerticalContentAlignment" Value="Top" />
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="KeyboardNavigation.TabNavigation" Value="Local" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Grid Background="{TemplateBinding Background}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="MouseOver" />
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Opacity" Duration="0" To=".55" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected" />
                            <VisualState x:Name="Selected" /> 
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Visibility" Duration="0">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Unfocused"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}"/>
                    <Rectangle x:Name="FocusVisualElement" Fill="{x:Null}" Stroke="{x:Null}" StrokeThickness="0" Visibility="Collapsed" RadiusX="1" RadiusY="1" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

ComboBoxItem:選択範囲とマウスオーバー背景色を変更するには、新しいControlTemplateを提供する必要があります。

<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="OverridesDefaultStyle" Value="true" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                <Border x:Name="Border" Padding="2" SnapsToDevicePixels="true" Background="Transparent">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="#FF47484C" /> <!-- Background mouse over colour -->
                                    </ColorAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="White" /> <!-- Foreground mouse over colour -->
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled" />
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected" />
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="#FF47484C" /> <!-- Background selection colour -->
                                    </ColorAnimationUsingKeyFrames>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="White" /> <!-- Foreground selection colour -->
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="SelectedUnfocused">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="Red" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ContentPresenter />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

CheckBoxControlTemplateBulletの右側にあるときにティックが後ろに表示されないように、新しいContentを提供する必要がありました(Fredrikの回答のおかげです) CheckBoxのデフォルトControlTemplate Stack Overflowの質問:

<SolidColorBrush x:Key="CheckBoxFillNormal" Color="#F4F4F4" />
<SolidColorBrush x:Key="CheckBoxStroke" Color="#8E8F8F" />
<Style x:Key="EmptyCheckBoxFocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Rectangle Margin="1" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="CheckRadioFocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Rectangle Margin="14,0,0,0" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="{x:Type CheckBox}" TargetType="{x:Type CheckBox}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="Background" Value="{StaticResource CheckBoxFillNormal}"/>
    <Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="FocusVisualStyle" Value="{StaticResource EmptyCheckBoxFocusVisual}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <BulletDecorator Background="Transparent" SnapsToDevicePixels="true">
                    <BulletDecorator.Bullet>
                        <Aero:BulletChrome BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" IsChecked="{TemplateBinding IsChecked}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"/>
                    </BulletDecorator.Bullet>
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </BulletDecorator>
                <ControlTemplate.Triggers>
                    <Trigger Property="HasContent" Value="true">
                        <Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
                        <Setter Property="Padding" Value="4,0,0,0"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

恐ろしいタイトルバーを削除して、デフォルトのWindows 8を表示するには:.NET 4.5にアップグレードし、付属のSystem.Windows.Controls.Ribbon以前に使用されていた個別の 'Microsoft Ribbon for WPF'(RibbonControlsLibrary)dllの代わりの名前空間ライブラリ。

残念ながら、Windows 8でSemiBoldプロパティのFontWeight設定を再現する方法を見つけられませんでした。これを行う方法を知っている人があれば、教えてください。

全体として、Windows 8への移行は苦痛で厄介な経験でした。この情報が、他の人の苦痛を少し軽減するのに役立つことを願っています。

10
Sheridan

問題(他の回答で説明)は、WPFがオペレーティングシステムのバージョンによって決定される既定のテーマを選択することです。

この動作をオーバーライドする必要があります。 この記事 の説明:

WPFには、各Windowsテーマ(Luna、Royale、Aero、およびフォールバックテーマ、Classic)に1つずつ、いくつかのテーマアセンブリが付属しています。通常、テーマは現在のシステムテーマに従って読み込まれますが、特定のアプリケーションを強制的にロードしたい場合があります。

それを実現するには、アプリケーションスタートアップイベントに次のコードを追加するだけです(この例では、Aeroテーマの使用方法を示します)。

Uri uri = new Uri(“PresentationFramework.Aero;V3.0.0.0;31bf3856ad364e35;component\\themes/aero.normalcolor.xaml”, UriKind.Relative);

Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary); 

バージョンと公開鍵トークンを指定することが重要です。それ以外の場合は、テーマアセンブリを実行可能ファイルのフォルダーにコピーする必要があります。マージされた辞書コレクションに追加する理由は、App.xamlファイルに追加した他のリソースを失いたくないからです。

3
Gusdor

カスタム(明示的)スタイルなしでWPFを使用する場合、標準のWindows 7 Aeroスタイルが使用されます。 Windows 8の場合は異なります(aero2)。

確認したい場合、アプリケーションはwindows7とwindows8でも同じように表示されます。マージン、パディング、フォントなどを自分で定義するカスタムスタイルを作成することをお勧めします。

2
Andras Sebo

問題は this に関連している可能性があります

現在、WPFリボンライブラリ内にバグがあり、ribbonwindowが使用されている場合、Windows 8テーマは適用されません。

さらに、Windows 7および8は、テキストボックスなどのコントロールに単純に異なるスタイルを使用します。複数のプラットフォーム用に開発する場合、Windowsのみであっても、サイズ、マージン、およびパディングが変わることに注意する必要があります。絶対値の代わりに、明示的に高さまたは幅を設定することを完全に回避することにより、コントロールにスペースの必要性を指示させる必要があります。

0
A. Wieser