Vertical separator in WPF Ribbon - c#

How can I add Vertical separator to WPF Ribbon, to RibbonGroup? I have tried something like that, but i got horizontal separator istead of vertical.
<r:RibbonGroup>
<r:RibbonButton Command="{StaticResource SomeButton}" />
<r:RibbonSeparator></r:RibbonSeparator>
<r:RibbonToggleButton IsChecked="False" Command="{StaticResource AnotherButton}"/></r:RibbonToggleButton>
</r:RibbonGroup>
So how can I make vertical separator?

This is how I would do it.
<ribbon:RibbonGroup.Resources>
<!-- Vertical Separator-->
<Style TargetType="{x:Type ribbon:RibbonSeparator}"
x:Key="KeyRibbonSeparatorVertical">
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="90"/>
</Setter.Value>
</Setter>
</Style>
</ribbon:RibbonGroup.Resources>

It looks like this doesn't work in the latest version (3.5.40729.1) anymore. The RibbonSeparator also doesn;t work, but you can use:
<Ribbon:RibbonControlGroup Height="55" Margin="5" Width="1" MinHeight="55" MaxWidth="1"/>

You can wrap what you have in a RibbonGroup, a vertical separator is created to the right of the group.
All I did was wrapped the first button in a RibbonGroup.
<ribbon:RibbonTab x:Name="HomeTab"
Header="Home">
<ribbon:RibbonGroup x:Name="Group1"
Header="Group1">
<ribbon:RibbonGroup>
<ribbon:RibbonButton x:Name="Button1"
LargeImageSource="Images\LargeIcon.png"
Label="Button1" Margin="-5" />
</ribbon:RibbonGroup>
<ribbon:RibbonButton x:Name="Button2"
SmallImageSource="Images\SmallIcon.png"
Label="Button2" />
<ribbon:RibbonButton x:Name="Button3"
SmallImageSource="Images\SmallIcon.png"
Label="Button3" />
<ribbon:RibbonButton x:Name="Button4"
SmallImageSource="Images\SmallIcon.png"
Label="Button4" />
</ribbon:RibbonGroup>
</ribbon:RibbonTab>

You can use a RibbonLabel, which can host any control in a RibbonGroup. It comes in very handy!
For a vertical line separator, you can try this:
<ribbon:RibbonLabel>
<Rectangle Height="56" Margin="2,0" Stroke="Silver"/>
</ribbon:RibbonLabel>
(Of course, you can style it as you see fit for the app..)

Works with me-
<my:RibbonSeparator Margin="5,0" Width="70" BorderBrush="Navy" BorderThickness="2">
<my:RibbonSeparator.RenderTransform>
<RotateTransform Angle="90" />
</my:RibbonSeparator.RenderTransform>
</my:RibbonSeparator>

This worked for me:
<Border Width="1" Margin="3" Height="175" Visibility="Visible" Background="#FFB9C9DA" />

Related

How do i get a Menu in the Window bar?

I would like to know how to get a menu in the window bar, the same as Visual studio does.
It would be good to be able to have File, Edit, etc on the left and the standard Minimize, Maximize and Close buttons on the right. Is this at all possible?
I have tried setting Window WindowStyle="None" and adding my own icons in the bar but it doesnt seem right but is this the only way?
This is what i have at the moment.
<Window
Title="MainWindow"
Height="{x:Static SystemParameters.PrimaryScreenHeight}"
Width="{x:Static SystemParameters.PrimaryScreenWidth}"
Closing="Window_Closing"
WindowState="Maximized">
You must create your custom window chrome using the WindowChrome class:
The Window element in WPF is actually hosted in a non-WPF (non-client) host. This host includes the title bar (caption) and the standard buttons, an icon and the actual frame. This is known as window chrome.
Usually you can only modify the client area of a Window. But whith the help of the WindowChrome class, WPF allows the client area to extend into the non-client area.
The disadvantage is that you would have to basically replicate the original non-client area in order to preserve the original look and feel. But after all you still get some basic behavior like maximizing the window on double click ou of the box.
The following example is very basic, but should give you an idea how to achieve your task:
I highly recommend to follow the provided link to the WindowChrome class and read the remarks section, which contains very valuable information.
You can use the actual system values provided by the static SystemParameters class to get the current dimension values e.g. SystemParameters.WindowResizeBorderThickness which you should use in your custom chrome style.
Also note that to allow WPF to capture mouse events on you custom chrome's input elements like buttons or menus you must set the attached property WindowChrome.IsHitTestVisibleInChrome on each relevant element to true:
WindowChrome.IsHitTestVisibleInChrome="True"
The very basic style that creates the above visual is as followed:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework">
<Style x:Key="WindowStyle" TargetType="{x:Type Window}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome NonClientFrameEdges="Right"
ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid Background="Transparent">
<AdornerDecorator>
<Border Background="Transparent" Margin="{x:Static SystemParameters.WindowNonClientFrameThickness}">
<ContentPresenter />
</Border>
</AdornerDecorator>
<ResizeGrip x:Name="WindowResizeGrip"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Visibility="Collapsed"
IsTabStop="false" />
<Grid Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
Background="#FF3F3F3F"
VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Custom window chrome -->
<StackPanel Grid.Column="0" Orientation="Horizontal"
Margin="{x:Static SystemParameters.WindowResizeBorderThickness}">
<Image Source="{TemplateBinding Icon}" />
<TextBlock Text="{TemplateBinding Title}"
TextTrimming="CharacterEllipsis"
VerticalAlignment="Center"
Margin="16,0" />
<Menu shell:WindowChrome.IsHitTestVisibleInChrome="True">
<MenuItem Header="CustomChromeMenu">
<MenuItem Header="Action" />
</MenuItem>
</Menu>
</StackPanel>
<StackPanel Grid.Column="1"
Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Width="45"
Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
ToolTip="Minimize window"
ToolTipService.ShowDuration="5000"
shell:WindowChrome.IsHitTestVisibleInChrome="True">
<TextBlock Foreground="{Binding RelativeSource={RelativeSource AncestorType=Control}, Path=Foreground}"
FontFamily="Segoe MDL2 Assets"
FontSize="11"
Text="" />
</Button>
<Button ToolTip="Maximize window"
Width="45"
Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
ToolTipService.ShowDuration="5000"
shell:WindowChrome.IsHitTestVisibleInChrome="True">
<TextBlock Foreground="{Binding RelativeSource={RelativeSource AncestorType=Control}, Path=Foreground}"
FontFamily="Segoe MDL2 Assets"
FontSize="11"
Text="" />
</Button>
<Button ToolTip="Close application"
ToolTipService.ShowDuration="5000"
Width="50"
Height="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}, Path=Top}"
shell:WindowChrome.IsHitTestVisibleInChrome="True">
<TextBlock Foreground="{Binding RelativeSource={RelativeSource AncestorType=Control}, Path=Foreground}"
FontFamily="Segoe MDL2 Assets"
FontSize="11"
Text="" />
</Button>
</StackPanel>
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ResizeMode"
Value="CanResizeWithGrip">
<Setter TargetName="WindowResizeGrip"
Property="Visibility"
Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
The title bar contains
An icon
A title
A minimize button
A maximize button
A close button
And that's all. You can't add anything.
In VS, the title bar is masked. The "title bar" you see is in fact the content of the window. That is, as you seemed to suspect, the only way.
That's also why tooltips on the three right buttons are in the OS language for most apps (because the title bar is managed by the system), but are in the app language for Visual Studio.
You have to set WindowStyle to None to mask the real title bar.
Then, inside your window, you should add a DockPanel and dock to the top an image and a menu on the left, and 3 buttons on the right.
The minimize button should change the WindowState to Minimized.
The maximize button should change the WindowState to either Normal or Maximized and its icon should be based on the WindowState.
The close button should call the Close() method and/or the Application.Current.Shutdown(0) method.
You should also subscribe to events like MouseLeftButtonDown, MouseLeftButtonUp and MouseMove to move the window.

Style all Buttons in a StackPanel the same way (UWP)

I want that all Buttons in a StackPanel have the same style.
Is there a similar possibility like in HTML / CSS?
For example, this makes in HTML the text of all buttons in the div with the class myBox blue:
CSS
.myBox Button{
color: blue;
}
HTML
<div class="myBox">
<button type="button">1</button>
<button type="button">2</button>
<button type="button">3</button>
</div>
When I have now this StackPanel, how can I make all Button text blue?
<StackPanel Orientation="Vertical" x:Name="ManagerMenu">
<Button x:Name="1" Content="1" />
<Button x:Name="2" Content="2" />
<Button x:Name="3" Content="3" />
</StackPanel>
You can do this by placing a default (= without an x:Key) Button style inside the stackpanel:
<StackPanel Orientation="Vertical" x:Name="ManagerMenu">
<StackPanel.Resources>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Blue" />
...
</Style>
</StackPanel.Resources>
<Button x:Name="1" Content="1" />
<Button x:Name="2" Content="2" />
<Button x:Name="3" Content="3" />
</StackPanel>
But you may want to base it on a pre-existing style for buttons or it will look rather flat.
You can create a resource tag and then use this to multiple elements.
Take a look at this.
https://msdn.microsoft.com/en-us/windows/uwp/controls-and-patterns/styling-controls
If you want to use existing style and apply it to all buttons:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="Button" BasedOn="{StaticResource MyButtonStyle}"/>
</StackPanel.Resources>
<Button x:Name="1" Content="1" />
<Button x:Name="2" Content="2" />
<Button x:Name="3" Content="3" />
</StackPanel>

Bind to child element of content template by name from outside

How can I get the binding from the outer ConnectingLine (a custom control that binds to FrameworkElements and connects them with a line) to the inner TextBlocks named "Top" and "Bottom" to work? Note that I want the whole FrameworkElements for position information.
<Grid>
<ConnectingLine From="{Binding ElementName=Button1.Top}" To="{Binding ElementName=Button2.Top}" />
<ConnectingLine From="{Binding ElementName=Button1.Bottom}" To="{Binding ElementName=Button2.Bottom}" />
<ToggleButton x:Name="Button1">
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<Rectangle x:Name="Top" />
<Rectangle x:Name="Bottom" />
</Grid>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ToggleButton x:Name="Button2">
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<Rectangle x:Name="Top" />
<Rectangle x:Name="Bottom" />
</Grid>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
</Grid>
My goal is to be able to bind from within XAML. Ideally with no extra fluff, but a solution involving a custom binding operator or attached properties might be acceptable.
Edit:
How I'd like to have the output:
Each distinct colored column is one of the templated ToggleButtons, already with one dashed ConnectingLine between Top and Bottom elements. The horizontal filled lines are what I'm interested in. Currently I'm achieving what I want from code-behind.
<ToggleButton x:Name="Button">
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<CheckBox x:Name="FindMe" IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsChecked}"/>
</Grid>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
Let me know if it works.

Actually using the Tile Control in MahApps Metro?

I have been working with MahApps Metro UI for couple days now and i have realy enjoyed it. WHen looking through their documentation, i wanted to use the tile control and make something along the lines of this:
Their documentation, located on this page: http://mahapps.com/controls/tile.html , only tells me this:
The following XAML will initialize a Tile control with its Title set to "Hello!" and its Count set to 1.
<controls:Tile Title="Hello!"
TiltFactor="2"
Width="100" Height="100"
Count="1">
</controls:Tile>
When i entered this into my simple application, i get one small rectangle. How am i actually supposed to use the control to mimic the Windows 8 start screen with tiles?
I'm currently building a large application using the MahApps Metro library and it's amazing! In terms of getting an app to look like the Windows 8 start screen, heres quick example I whipped up.
XAML
<Window x:Class="Win8StartScreen.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
Title="MainWindow" Height="513" Width="1138" WindowState="Maximized" WindowStyle="None" Background="#191970">
<Window.Resources>
<Style x:Key="LargeTileStyle" TargetType="mah:Tile">
<Setter Property="Width" Value="300" />
<Setter Property="Height" Value="125" />
<Setter Property="TitleFontSize" Value="10" />
</Style>
<Style x:Key="SmallTileStyle" TargetType="mah:Tile">
<Setter Property="Width" Value="147" />
<Setter Property="Height" Value="125" />
<Setter Property="TitleFontSize" Value="10" />
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="87*"/>
<ColumnDefinition Width="430*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="83*"/>
<RowDefinition Height="259*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
Text="Start"
FontWeight="Light"
Foreground="White"
FontSize="30"
FontFamily="Segoe UI" />
<WrapPanel Grid.Row="1" Grid.Column="1" Width="940" Height="382" HorizontalAlignment="Left" VerticalAlignment="Top">
<mah:Tile Title="Mail" Style="{StaticResource LargeTileStyle}" Content="ImageHere" Background="Teal" Margin="3"/>
<mah:Tile Title="Desktop" Style="{StaticResource LargeTileStyle}" Margin="3">
<mah:Tile.Background>
<ImageBrush ImageSource="Images/windesktop.jpg" />
</mah:Tile.Background>
</mah:Tile>
<mah:Tile Title="Finance" Style="{StaticResource LargeTileStyle}" Background="Green" />
<mah:Tile Title="People" Style="{StaticResource LargeTileStyle}" Background="#D2691E" />
<mah:Tile Title="Weather" Style="{StaticResource LargeTileStyle}" Background="#1E90FF" />
<mah:Tile Title="Weather" Style="{StaticResource SmallTileStyle}" Background="#1E90FF" />
<mah:Tile Title="Store" Style="{StaticResource SmallTileStyle}" Background="Green" />
</WrapPanel>
</Grid>
</Window>
There are lots of ways to do this to make it cleaner and more reusable using styles and templates, but this was just a quick way to show the use of the Tiles control.

Embedding an Image Object Inside a Button

I currently have an example that embeds an image object inside of a button.
the xaml looks like this:
<Button Height="194" HorizontalAlignment="Left"
Margin="23,27,0,0" Name="button1" VerticalAlignment="Top" Width="216"
Click="button1_Click">
<Image Name="image1" Stretch="Fill"
Source="/WPFButtonEmbedded;component/BenderInSpaceFace.png"
Height="105" VerticalAlignment="Bottom" Width="158" />
</Button>
However, when I try to recreate this myself i seem to get an error. I though that maybe they were binded togeather but looking at the example it doesnt seem that way.
Also the "image1" is an image that i added by clicking add exising item.
Any comments or suggestions are appreciated.
Thanks.
if you need to set image as Content
you can do it by setting style in resource
<Window.Resources>
<Image x:Key="Img" Source="/WPFButtonEmbedded;component/BenderInSpaceFace.png" Stretch="Fill"/>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Content" Value="{StaticResource Img}" />
</Style>
</Window.Resources>
then you can set the Style of the Button
<Button Style="{StaticResource ButtonStyle}" />

Categories