5

Given a button (or a combobox, or any control for that matter):

<Button x:Name="button" Command="{Binding DoStuff}" Margin="10,0,5,5" Content="Do Stuff!" Style="{StaticResource buttonDefaults}"/>

With the style:

<Style x:Key="buttonDefaults" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
        <Style.Resources>
            <ResourceDictionary Source="/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml"/>
        </Style.Resources>
        <Setter Property="Background">
            <Setter.Value>
                <RadialGradientBrush>
                    <GradientStop Color="#F4083268" Offset="1"/>
                    <GradientStop Color="#FE5C9247"/>
                </RadialGradientBrush>
            </Setter.Value>
        </Setter>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="FontFamily" Value="Arial"/>
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="Focusable" Value="False"/>
    </Style>

It looks very different in Windows 8 than it does in Windows 7.

Now, the strange part is that in the DESIGNER, everything looks perfect on a Windows 8 machine as if it were Windows 7... But at runtime, the style isn't "applied."

On the other hand, it looks perfect on Windows 7 in both the designer and runtime. Is there a way to fix this?

Additional Details:

With the RD in the Style:

    <Style x:Key="buttonDefaults" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
        <Style.Resources>
            <ResourceDictionary Source="/PresentationFramework.Aero,Version=4.0.0.0,Culture=Neutral,PublicKeyToken=31bf3856ad364e35,processorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml"/>
        </Style.Resources>
        <Setter Property="Background">
            <Setter.Value>
                <RadialGradientBrush>
                    <GradientStop Color="#F4083268" Offset="1"/>
                    <GradientStop Color="#FE5C9247"/>
                </RadialGradientBrush>
            </Setter.Value>
        </Setter>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="FontFamily" Value="Arial"/>
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="Focusable" Value="False"/>
    </Style>

The result looks like:

With the RD in the Application scope:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/PresentationFramework.Aero,Version=4.0.0.0,Culture=Neutral,PublicKeyToken=31bf3856ad364e35,processorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <Style x:Key="buttonDefaults" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
            <Setter Property="Background">
                <Setter.Value>
                    <RadialGradientBrush>
                        <GradientStop Color="#F4083268" Offset="1"/>
                        <GradientStop Color="#FE5C9247"/>
                    </RadialGradientBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="FontFamily" Value="Arial"/>
            <Setter Property="FontSize" Value="16"/>
            <Setter Property="Focusable" Value="False"/>
        </Style>
    </ResourceDictionary>
</Application.Resources>

The result looks like:

I'd like to apply the visuals of the second one to just a single style, not the entire application.

Community
  • 1
  • 1
Shaku
  • 670
  • 1
  • 8
  • 19

4 Answers4

5

I think your problem stems from the fact that you're using partial assembly name. According to MSDN, GAC isn't searched for assemblies when you're using partial assembly names.

Edit after your additional detail update:

After looking at your screenshots, I finally understand your new problem. The problem has to do with scoping of resources. Your button inherits the button style before you add the aero override when you're defining style inside the control. You can easily adjust that by adding a Panel on top of the control you want and use it as a scope container for resource. Updated code as follows:

<Window x:Class="AeroTestSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="191" Width="246">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button Content="Do Stuff!" Padding="10" Margin="10"/>
        <StackPanel>
            <StackPanel.Resources>
                <ResourceDictionary Source="/PresentationFramework.Aero,Version=4.0.0.0,Culture=Neutral,PublicKeyToken=31bf3856ad364e35,processorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml"/>
            </StackPanel.Resources>
            <Button Content="Do Stuff!" Padding="10" Margin="10">
                <Button.Resources>
                    <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
                        <Setter Property="Background">
                            <Setter.Value>
                                <RadialGradientBrush>
                                    <GradientStop Color="#F4083268" Offset="1"/>
                                    <GradientStop Color="#FE5C9247"/>
                                </RadialGradientBrush>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="BorderBrush" Value="Transparent"/>
                        <Setter Property="Foreground" Value="White"/>
                        <Setter Property="FontFamily" Value="Arial"/>
                        <Setter Property="FontSize" Value="48"/>
                        <Setter Property="Focusable" Value="False"/>
                    </Style>
                </Button.Resources>
            </Button>
        </StackPanel>
    </StackPanel>
</Window>

Screenshot of this in effect:

Screenshot with mouse over effect

Maverik
  • 5,619
  • 35
  • 48
  • I'm getting "Assembly PresentationFramework.Aero ..." is not referenced by this project. I have PresentationFramework.Aero in the references for the project, what am I missing? Could you provide your solution files? – Shaku Mar 24 '14 at 19:17
  • A note: `Source="/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml"` works fine, but the fully qualified name gives me the above error. I grabbed the assembly info and it matched what you have in your answer, so I'm not sure what I'm getting wrong. – Shaku Mar 24 '14 at 23:08
  • I saw that error too but it was a Resharper error in my case that I ignored. The project ran fine. I'll upload a new solution from this code since I deleted my own copy after doing the sample :) – Maverik Mar 25 '14 at 12:15
  • I've uploaded it to [Github](https://github.com/Venomed/AeroTestSample) and confirmed it to be working with .net 4.0/4.5/4.5.1 Even though designer still complains about not referencing, you can be sure it is referencing because you can see autocomplete working on component section. Even if you don't reference the Aero assembly, it'll still work fine but you'll lose intellisense on it. – Maverik Mar 25 '14 at 12:40
  • Ah, that's very strange. There's still one problem though -- It doesn't work as expected when the reference to the resource dictionary is within the style itself. The solution you gave has the RD as a global resource. Ideally I'd avoid applying the resource to everything since there's only a few things that are messed up between W7 and W8. – Shaku Mar 25 '14 at 17:53
  • I'm sorry I don't follow? My github solution shows it can work at global level. My code here shows that it works equally well at a single control level. What am I missing? – Maverik Mar 26 '14 at 14:04
  • As in my original post, I have the reference to the RD inside the button style. I'm trying to avoid putting the RD as an application level resource because I don't want to override everything with aero -- just specific styles. Your solution shows it as an application level RD. – Shaku Mar 26 '14 at 19:00
  • My solution equally shows it *here* **INSIDE** the button. The solution is literally same, just trying to prove that both approaches work fine. If a simple copy paste is too much to ask to confirm what I've already confirmed, I'm happy to leave the bounty alone. – Maverik Mar 26 '14 at 19:18
  • Sorry to upset you. I've added additional details to my original post with images of the results for having the RD within the Style vs. in the Application scope. Hopefully this clears up the issue I'm facing. – Shaku Mar 26 '14 at 20:19
  • Sorry for getting upset, I couldn't understand what you meant until you posted the screenshot. Updated code with your new information. – Maverik Mar 27 '14 at 12:37
  • No problem. Your new solution is a strange workaround, but it works! Thanks so much! Bounty awarded to you. – Shaku Mar 28 '14 at 18:33
  • Hehe it isn't strange if you think of it as scoping mechanism like additional { } in c#. Happy coding! :D – Maverik Mar 29 '14 at 10:38
1

The designer has a bug, that's why it shows the wrong style in Windows 8. I believe the problem stems from the fact that the Windows 7 and 8 system themes have the same name (aero.normalcolor), and WPF has to manually check for Windows 8 and use the theme name aero2.normalcolor instead.

As for your problem, I would not load the entire (huge) theme resource dictionary just to style a single button. Instead, copy the button style and template from aero.normalcolor.xaml (located under the Blend installation directory, Blend\SystemThemes\Wpf\v4.0\aero.normalcolor.xaml) into your resource dictionary. WPF doesn't actually use any resources from the OS, so that code would work under any OS version.

Eli Arbel
  • 22,391
  • 3
  • 45
  • 71
0

Is there a practical reason that you join a resource dictionary PresentationFramework.Aero in your Style? If I'm not mistaken, for each version of Windows, it may be different, respectively due to this can be different View. Also I think in this situation, not make much sense to specify for Style BasedOn, you can also try to remove it.

There are a few tips that can help:

  • Try to remove the reference to this ResourceDictionary

  • Try to move all the resource dictionaries in the App.xaml file where they belong out there

  • Create for each Control a ControlTemplate, that his view was "constant" for all versions of Windows

Community
  • 1
  • 1
Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
  • Reason for the RD: To show concise code on stackoverflow. That line simply defines the style to use the RD which also continues to answer your second question about `BasedOn`. The reason `BasedOn` is there is because it grabs its' data from the style's RD (in this case, W7's aero theme). Moving the style into a View's grid works -- but I want to use it as a style so it can be applied to the entire application. I'll give the ControlTemplate a go. – Shaku Mar 22 '14 at 09:35
0

I am not sure you would like to fix the Windows 8 design mode or you would like to create an app, which looks the same on different OSs. In case of the second here is a blog post, how to force WPF / .NET to use the same style on different Windows versions (e.g. XP, 7 and 8).

Andras Sebo
  • 1,120
  • 8
  • 19