Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF RibbonWindow + Ribbon = Title outside screen?

I'm trying out Ribbon control in combination with RibbonWindow, however they fail even in trivial experiments.

  1. Created new WPF Application
  2. Changed code to example from MSDN
  3. Added reference to System.Windows.Controls.Ribbon and got rid of ribbon: prefix (why are examples outdated?).
  4. Added two icons (16x16 and 32x32).
  5. Executed the application and saw this (Notepad for reference):

I can already see numerous problems:

  1. Border is tiny. A normal window has a big border, WPF Ribbon app has tiny. The title height is smaller too.
  2. Border is blurry. When a normal window is focused, it's border is black. WPF app's border is greyish (black can be seen in corners; something is drawn over the borders?).
  3. Application icon is misplaced. It's glued to the top-left corner.
  4. Application title is misplaced. It's glued to the top.

Let's move the toolbar to the bottom. Now we see this:

Buttons are outside of the toolbar.

And finally, let's maximize the window:

Half of the header disappeared outside of the screen (technically window is outside of the screen by 8 pixels on every side, but other apps aren't confused by this).

I'm using Windows 7, Aero, single monitor, nothing special. I'm afraid to test the application on Windows 8...

Any chance to fix this?

like image 471
Athari Avatar asked Sep 24 '12 14:09

Athari


4 Answers

The real problem

Under the hood, the WindowChrome class binds its ResizeBorderThickness to SystemParameters.WindowResizeBorderThickness which in turns uses the Win32 API GetSystemMetrics to determine the system border size.

However, the behavior of this method changes depending of the subsystem version set in the executable PE header. If compiled only for Windows Vista and later (version >= 6.0), it will return thinner borders than if compiled for older operating systems. More information on this in this SO answer.

When compiling against .NET 4.5, the C# compiler sets this version to 6.0 since .NET 4.5 cannot be used on XP. However, the WindowChrome class seems to rely on the legacy behavior and thus fails to calculate the glass size correctly on Windows Vista and 7.

Solutions

Use .NET 4

You can compile against .NET 4 to force the compiler to use 4.0 as its subsystem version value. The ribbon is available for WPF 4 as a separate download. Note that even with this solution, you should uncheck "Enable the Visual Studio hosting process" in the project properties for debugging purposes. Otherwise, the vshost.exe process will be used, which is flagged with a subsystem version of 6.0.

Change the subsystem version

Edit: Olly provided a way to do this in the comments:

Add a property in the project file <subsystemversion>5.01</subsystemversion> that falsely indicates that the code can run on Windows XP.

Ignore the system

You can change the WindowChrome.WindowChrome attached property on your window and use the values that you want, thus completely ignoring the system values. You should never do that, but you can.

Fill a bug

There is an existing bug on Connect about the change in behavior of GetSystemMetrics but it all comes down to the subsystem version so it's rather a feature from a Microsoft view point. However, the WindowChrome class should really be fixed to work correctly under Vista/7, especially since it's now built in .NET 4.5.

like image 178
Julien Lebosquain Avatar answered Sep 25 '22 13:09

Julien Lebosquain


For anyone who reads this question, I'm answering it myself. Forget about the horrible bundled ribbon control and use something else. Look for some of the alternatives here: What is the Best WPF Ribbon Control Suite? (like all good questions, it's closed though).

So far, Fluent Ribbon Control Suite looks like the best free option to me. Basic functionality just works (no problems with borders and maximizing, resising window isn't slow as hell etc.). It has Office styles and preserves them if glass is disabled (that means you won't see Windows9x-ish window in Metro). Its interface (backstage, QAT) is more like Office 2010.

Maybe in some distant future, Microsoft will fix its Ribbon, but for now, look for alternatives.

like image 25
Athari Avatar answered Sep 24 '22 13:09

Athari


Here is another WorkAround, very easy and simple way. Simply add a negative margin at the toolbar. You need to keep the original Window Class and not the RibbonWindow !

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Application Name" Height="350" Width="525" Loaded="Window_Loaded" SizeChanged="Window_SizeChanged">

Just add this margin to the Ribbon Title

<Ribbon Title="" Foreground="#333333" Margin="0,-22,0,0">

Now when you maximize the window, everything stay right

like image 34
Yannick Turbang Avatar answered Sep 24 '22 13:09

Yannick Turbang


I had the same Problem with the title in the RibbonWindow. I solved it by setting the global style of the TextBlock within the RibbonTitlePanel.

    <Style TargetType="{x:Type TextBlock}"> 
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type primitives:RibbonTitlePanel}},Path=Visibility}" Value="Visible"></Condition>
                <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type RibbonWindow}},Path=WindowState}" Value="Maximized"></Condition>
            </MultiDataTrigger.Conditions>
            <MultiDataTrigger.Setters>
                <Setter Property="VerticalAlignment" Value="Center"></Setter>
            </MultiDataTrigger.Setters>
        </MultiDataTrigger>
    </Style.Triggers>
</Style>
like image 34
troYman Avatar answered Sep 23 '22 13:09

troYman