WPF: Map UserControl properties to its children - wpf

The short version of my question is: Can properties of the UserControl be made available to the children of the UserControl without applying to the UserControl at the same time?
The long version: I am trying to create a "ButtonInput" which is a text box with a bitmap button at the right side, inside of the text box's border. This is pretty much how the search boxes look on many web sites (or in Visual Studio), with a magnifying glass at the right side.
The UserControl definition is:
<UserControl x:Class="Test.Controls.ButtonInput"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Test.Controls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="Transparent">
<Border
Name="Border"
CornerRadius="6"
Padding="4"
Margin="2 2 2 2"
Background="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType=local:ButtonInput, AncestorLevel=1}}"
BorderBrush="{Binding Path=BorderBrush, RelativeSource={RelativeSource FindAncestor, AncestorType=local:ButtonInput, AncestorLevel=1}}"
BorderThickness="1"
>
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox x:Name="tbInput"
Grid.Column="0"
MaxLines="1"
Background="Transparent"
Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=local:ButtonInput, AncestorLevel=1}}"
Text="{Binding Path=Text, RelativeSource={RelativeSource FindAncestor, AncestorType=local:ButtonInput, AncestorLevel=1}}"
BorderThickness="0"/>
<Button Width="24" Grid.Column="1" Click="Button_Click">
<Button.Template>
<ControlTemplate>
<Image x:Name="imgIcon"
Source="{Binding Path=Source, RelativeSource={RelativeSource FindAncestor, AncestorType=local:ButtonInput, AncestorLevel=1}}" />
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</Border>
</Grid>
</UserControl>
I place this control in a test Window.
<Window x:Class="Test.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Test"
xmlns:controls="clr-namespace:Test.Controls"
mc:Ignorable="d"
Title="TestWindow" Height="450" Width="800">
<Grid>
<StackPanel Orientation="Horizontal" Height="380" Width="402">
<Label Content="Password" Width="75" VerticalAlignment="Center"/>
<controls:ButtonInput x:Name="biTest" Source="Resources/img/password.png" Width="300" Height="35" Background="Orange" Foreground="Red" BorderBrush="Black" ButtonClick="ButtonInput_ButtonClick" />
</StackPanel>
</Grid>
</Window>
The problem I have is that I expect to have only what is inside the border colored orange, but instead the orange bleeds outside the border. I traced the problem to the way the Live Visual Tree looks like:
(ButtonInput)
(Border)
(ContentPresenter)
(Grid)
Border (Border)
(Grid)
tbInput (TextBox)
(Button)
The first Border is not in my control definition, but its background is Orange as inherited from the ButtonInput.
I did try an alternative: instead of using child controls for the content of the UserControl, I used a ControlTemplate with the same content. In this case, the executable looked OK (rounded rectangle with black border and orange background, no bleeding outside the border), but the designer in Visual Studio does not show anything. There is literally a blank space where the ButtonInput should be.
So, is there a way to prevent the properties set on the UserControl to apply to the first Border? Background is one example but there are other properties that I want to make use of the same way.

What's happening here is that your "ButtonInput" control isn't actually a button, it's a user control which just so happens to have a button on it. So when you set the background in the <controls:ButtonInput> tag on your main window you're effectively saying "ignore everything this user control says about the color of it's entire background because I'm now overriding it".
There are several ways around this, but the easiest one from the UserControl's perspective is to use the one last weapon in its arsenal: the template. Overriding the template in a control effectively says "I'm no longer going to be displayed the way a control of my type normally is, so all the usual settings won't apply unless I explicitly use them. That's as simple as doing this in your ButtonInput xaml:
<UserControl.Template>
<ControlTemplate>
<!-- all your old xaml code goes here -->
<Grid Background="Transparent">
<Border
Name="Border"
CornerRadius="6"
Padding="4"
<!-- etc -->
</ControlTemplate>
</UserControl.Template>
Which results in the following:
Truth be told, there are few cases in WPF where custom controls are actually needed, and this is almost certainly one of them. WPF is more than capable of supporting functionality like this with styles and templates alone. But this answer should suit your needs in the short term.
EDIT: If you want the control to be visible in the designer then populate it with a regular control and template that instead, it's what you probably should be doing anyway. Now your xaml should look like this:
<UserControl x:Class="WpfTestApp.Controls.ButtonInput"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfTestApp.Controls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
x:Name="_this">
<UserControl.Resources>
<ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type Button}">
<Grid Background="Transparent">
<Border
Name="Border"
CornerRadius="6"
Padding="4"
Margin="2 2 2 2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1"
>
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox x:Name="tbInput"
Grid.Column="0"
MaxLines="1"
Background="Transparent"
Text="{Binding ElementName=_this, Path=Text, Mode=TwoWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
Foreground="{TemplateBinding Foreground}"
BorderThickness="0" Margin="0,-1,0,1"/>
<Button Width="24" Grid.Column="1">
<Button.Template>
<ControlTemplate>
<Image x:Name="imgIcon" />
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</UserControl.Resources>
<Button x:Name="biTest" Width="300" Height="35" Background="Orange" Foreground="Red" BorderBrush="Black" Template="{StaticResource ButtonTemplate}" />
</UserControl>
You haven't addressed the Text binding in your question, the code above is expecting a dependency property in the UserControl code behind:
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(ButtonInput), new PropertyMetadata(String.Empty));
And you now use it like this:
<controls:ButtonInput x:Name="biTest" Width="300" Height="35" Text="{Binding MyText, Mode=TwoWay}" />

Related

How to resize button content in WPF with a viewbox while maintaining the Font size?

I am creating an app and I need the content of a button to be resizable when the user minimises their screen. We know that the viewbox does this in WPF; it's the easiest way to resize text automatically.
This is the code for [the top part] of the button, I apologise about the formatting:
<Button Grid.Row="0"
Grid.Column="2"
Background="#3767B0"
Style="{DynamicResource IconStyle}"
BorderBrush="Transparent">
<Button.ContentTemplate>
<DataTemplate >
<Viewbox>
<TextBlock></TextBlock>
</Viewbox>
</DataTemplate>
</Button.ContentTemplate>
</Button>
What I want to get out of this is: to use the Viewbox in WPF to resize the content of this button while maintaining the font size of the content.
This resizes the content of the button, but the button's content is not maintained:
This is how it should look like with a viewbox, and should resize properly:
By maintaining I mean I want to use the viewbox whilst the content of the button (which is a child of the viewbox) looks exactly how it would've with a font size of 22. You can see how I want it to look like with a viewbox inside the content of the button in the image above. I've tried to be as clear as possible on this. Maybe I don't understand how the viewbox works?
Someone requested the icon style. Here is the icon style code:
<Style TargetType="Button"
x:Key="IconStyle"
BasedOn="{StaticResource ButtonStyle1}">
<Setter Property="FontFamily"
Value="Segoe MDL2 Assets" />
<Setter Property="Grid.RowSpan"
Value="2" />
<Setter Property="Padding"
Value="0,0,0,60" />
<Setter Property="Foreground"
Value="White" />
<Setter Property="FontSize"
Value="80" />
<Setter Property="Background"
Value="#307A85" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="15"
ShadowDepth="0"
Opacity="0.4"
Color="Black" />
</Setter.Value>
</Setter>
If I understand correctly what you need to implement, then remove the ViewBox and set the explicit dimensions of the TextBlock.
I am showing an arbitrary example, but for your task, you yourself choose the required dimensions and alignment.
<Button Background="#3767B0"
Style="{DynamicResource IconStyle}"
BorderBrush="Transparent">
<Button.ContentTemplate>
<DataTemplate >
<TextBlock Width="300"
Height="300"
FontSize="200"
Text=""/>
</DataTemplate>
</Button.ContentTemplate>
</Button>
Hello my good friends on Stack OverFlow. I have found a solution to this problem, all I had to do was set the padding of the TextBlock:
<!--FEEDBACK BUTTON-->
<Button Grid.Row="3"
Grid.Column="2"
Grid.RowSpan="2"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
BorderThickness="3"
Name="Feedback_Button"
BorderBrush="White"
Click="Button_Click"
MouseEnter="Button_MouseEnter"
MouseLeave="Button_MouseLeave">
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}" />
</ControlTemplate>
</Button.Template>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="218*" />
<RowDefinition Height="68*" />
</Grid.RowDefinitions>
<Button Grid.Row="0"
Grid.Column="2"
Background="#3767B0"
FontFamily="Segoe MDL2 Assets"
Foreground="White"
Content="Feedback"
BorderBrush="Transparent">
<Button.ContentTemplate>
<DataTemplate>
<Viewbox>
<TextBlock Padding="15"></TextBlock>
</Viewbox>
</DataTemplate>
</Button.ContentTemplate>
</Button>
<Button Grid.Row="4"
Grid.Column="2"
Background="#FF2D5BA0"
FontFamily="Segoe UI Light"
Style="{StaticResource TextButton}"
Content="Feedback"
BorderBrush="Transparent">
<Button.ContentTemplate>
<DataTemplate>
<Viewbox>
<TextBlock Padding="15">Feedback</TextBlock>
</Viewbox>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</Grid>
</Button>
<!--FEEDBACK BUTTON-->
Thank you my friends for your help, such a simple solution I would've expected you guys to know this.
Cheers,
#Tom Joney , I do not quite clearly understand what you need to implement, so I cannot give an exact answer.
General answer for using different layout.
The ViewBox scales the content to the maximum allowed size provided by the outer container.
The Padding property of a container sets the size of the border between the container and its contents.
The element's Margin property sets the size of the border between the element and its containing container.
That is, these are very close properties.
In our case, the main content is Text.
Therefore, there is no difference how to set the size of the border: between the Text and the containing TextBlock (TextBlock.Padding) or between the TextBlock and its containing outer container (the Grid line).
Look at two examples in which I set the background colors for better clarity.
Example with Padding
<Window x:Class="ViewBoxScaleText.PaddingWind"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ViewBoxScaleText"
mc:Ignorable="d"
Title="PaddingWind" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Background="LightGreen">
<Viewbox>
<TextBlock Padding="15"
Background="LightBlue"
Text="{Binding Text, ElementName=tb}"/>
</Viewbox>
</Border>
<TextBox x:Name="tb" Grid.Row="1" Margin="10" Text="Feedback"/>
</Grid>
</Window>
Example with Margin
<Window x:Class="ViewBoxScaleText.MarginWind"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ViewBoxScaleText"
mc:Ignorable="d"
Title="MarginWind" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Background="LightGreen">
<Viewbox>
<TextBlock Margin="15"
Background="LightBlue"
Text="{Binding Text, ElementName=tb}"/>
</Viewbox>
</Border>
<TextBox x:Name="tb" Grid.Row="1" Margin="10" Text="Feedback"/>
</Grid>
</Window>
The color of the regions shows that the containers have different sizes, but this does not affect the location and size of the Text.
Try to enter text in the field at the bottom of the window to see how the amount of text affects its size and the size of the border.
Since the ViewBox scales the entire content, both the text size size and are the border scaled.
If in the examples above you change the size of the window, you will see that the size of the container occupied by the text also changes.
This happens due to the fact that the setting of the border occurs inside the ViewBox and thus we set the size of the border, in fact, in units relative to the size of the text.
Changing the size of the text will change the size of the face and therefore change the overall container for the text.
Here is an example with the ability to change the font size in the very bottom margin of the window.
See how this affects the size of the border.
<Window x:Class="ViewBoxScaleText.FontSizeWind"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ViewBoxScaleText"
mc:Ignorable="d"
Title="FontSizeWind" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Background="LightGreen">
<Viewbox>
<TextBlock Margin="15"
Background="LightBlue"
Text="{Binding Text, ElementName=tbText}" FontSize="{Binding Text, ElementName=tbFontSize}"/>
</Viewbox>
</Border>
<TextBox x:Name="tbText" Grid.Row="1" Margin="10" Text="Feedback"/>
<TextBox x:Name="tbFontSize" Grid.Row="2" Margin="10" Text="80"/>
</Grid>
</Window>
Here are some more layout options in one XAML so that you can launch, check their behavior and choose the one that suits you
<Window x:Class="ViewBoxScaleText.MultiVariantWind"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ViewBoxScaleText"
mc:Ignorable="d"
Title="MultiVariantWind" Height="750" Width="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Background="LightGreen" Margin="5">
<Viewbox>
<TextBlock Margin="15"
Background="LightBlue"
Text="{Binding Text, ElementName=tbText}" FontSize="{Binding Text, ElementName=tbFontSize}"/>
</Viewbox>
</Border>
<Border Background="LightGreen" Margin="5" Grid.Row="1">
<Viewbox Margin="15">
<TextBlock
Background="LightBlue"
Text="{Binding Text, ElementName=tbText}" FontSize="{Binding Text, ElementName=tbFontSize}"/>
</Viewbox>
</Border>
<Border Background="LightGreen" Margin="5" Grid.Row="2">
<Viewbox Width="150" Height="150">
<TextBlock
Background="LightBlue"
Text="{Binding Text, ElementName=tbText}" FontSize="{Binding Text, ElementName=tbFontSize}"/>
</Viewbox>
</Border>
<Border Background="LightGreen" Margin="5" Grid.Row="3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15*"/>
<ColumnDefinition Width="70*"/>
<ColumnDefinition Width="15*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="15*"/>
<RowDefinition Height="70*"/>
<RowDefinition Height="15*"/>
</Grid.RowDefinitions>
<Viewbox Grid.Row="1" Grid.Column="1">
<TextBlock
Background="LightBlue"
Text="{Binding Text, ElementName=tbText}" FontSize="{Binding Text, ElementName=tbFontSize}"/>
</Viewbox>
</Grid>
</Border>
<TextBox x:Name="tbText" Grid.Row="4" Margin="10" Text="Feedback"/>
<TextBox x:Name="tbFontSize" Grid.Row="5" Margin="10" Text="80"/>
</Grid>
</Window>

How could providing Parent Window as Pattern - WPF

Consider I have 4 Window on my project and I try to provide specific Closing button and one Title
How could I make a object of window and all of window use it as Pattern.
Here is Example of what we have for pattern window:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStyle="None" AllowsTransparency="True" >
<Grid>
<Button Content="Close" Height="40" VerticalAlignment="Top" HorizontalAlignment="Right"/>
<TextBlock VerticalAlignment="Top" HorizontalAlignment="Center" X:Name="WindowTitle/>
</Grid>
</Window>
How could I use for all of my Window as pattern. Thanks
Actually, there is no need to write a parent window. You can use Style and Template instead. It's more convenient and is recommended by Microsoft WPF Team.
Write the code below into your App.xaml and you'll get the picture above:
<Application x:Class="Walterlv.Demo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
.........>
<Application.Resources>
<Style x:Key="Style.Window.Default" TargetType="Window">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="Close" Height="40" VerticalAlignment="Top" HorizontalAlignment="Right"/>
<TextBlock Grid.Row="0" VerticalAlignment="Top" HorizontalAlignment="Center"
Text="{TemplateBinding Title}"/>
<Border Grid.Row="1" BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}">
<!-- This is the container to host your Window.Content -->
<ContentPresenter/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
And you can use only one property Style to share such a "pattern":
<Window x:Class="Walterlv.Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Style="{StaticResource Style.Window.Default}">
</Window>
You can define different kinds of styles in the App.xaml file and select anyone in your XxxWindow.xaml you need.

Issue templating RadioButton in Silverlight 5

I try to apply a really simple ControlTemplate to a RadioButton. But that cause in a weird behavior.
As Long as I´m just clicking the Label everything works fine, but when I click the button control itself it never changes again. Here the complete code of the control:
<UserControl x:Class="RadioButtonDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<ControlTemplate TargetType="RadioButton" x:Key="RadioButtonTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{TemplateBinding Content}"/>
<RadioButton IsChecked="{TemplateBinding IsChecked}" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
<Style TargetType="RadioButton" x:Key="RadioButtonStyle">
<Setter Property="Template" Value="{StaticResource RadioButtonTemplate}"/>
</Style>
</UserControl.Resources>
<StackPanel>
<RadioButton Content="Textbox diabled" GroupName="Group1" Style="{StaticResource RadioButtonStyle}"/>
<RadioButton x:Name="EnabledButton" Content="Textbox enabled" GroupName="Group1" Style="{StaticResource RadioButtonStyle}"/>
<TextBox IsEnabled="{Binding IsChecked, ElementName=EnabledButton}"/>
</StackPanel>
Can someone help?
Please get default style from following link,
http://msdn.microsoft.com/en-us/library/cc296247(v=vs.95).aspx
Use the template by just swapping content and button(:-( code is bulk).

WPF Net Framework 3.5 Window Metro Style

I want to make Window with Metro style.
I found the 3 following libraries:
http://elysium.asvishnyakov.com/en/
https://github.com/MahApps/MahApps.Metro
http://mui.codeplex.com/
All are for Net Framework 4+.
Is there anything for 3.5?
I also tried to make it on my own (Didnt finish - still need to design it and add Resize [which I dont know how]) but I dont really like how it's made...:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" x:Class="Windows_Hider.MainWindow"
Title="Windows Hider" Height="350" Width="525" WindowStartupLocation="CenterScreen"
AllowsTransparency="True"
ResizeMode="CanResize" WindowStyle="None" BorderBrush="Black" BorderThickness="1" Icon="windowshider.ico">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top">
<Image Width="24" Height="24" Source="{Binding Icon, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding Title, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>
</StackPanel>
<Grid MouseDown="Grid_MouseDown" Background="Transparent"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Grid.Row="0">
<Button ToolTip="minimize" Background="White">
<Grid Width="30" Height="25">
<TextBlock Text="0" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="3.5,0,0,3" />
</Grid>
</Button>
<Grid Margin="1,0,1,0">
<Button x:Name="Restore" ToolTip="restore" Visibility="Collapsed">
<Grid Width="30" Height="25" UseLayoutRounding="True">
<TextBlock Text="2" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="2,0,0,1" />
</Grid>
</Button>
<Button x:Name="Maximize" ToolTip="maximize">
<Grid Width="31" Height="25">
<TextBlock Text="1" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="2,0,0,1" />
</Grid>
</Button>
</Grid>
<Button x:Name="Close" ToolTip="close">
<Grid Width="30" Height="25">
<TextBlock Text="r" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="0,0,0,1" />
</Grid>
</Button>
</StackPanel>
</Grid>
</Grid>
</Window>
Ok, it took me few days but in the end I managed to do something.
I had to make it by myself because there's no Metro Window for Net Framework 3.5.
I combined some of the references below:
Launch window's System Menu on custom window
http://www.codeproject.com/Articles/107994/Taskbar-with-Window-Maximized-and-WindowState-to-N
http://blog.magnusmontin.net/2013/03/16/how-to-create-a-custom-window-in-wpf/
http://codekong.wordpress.com/2010/11/10/custom-window-style-and-accounting-for-the-taskbar/
http://blog.creativeitp.com/posts-and-articles/c-sharp/simple-methods-to-drag-and-resize-your-c-transparent-wpf-application-with-the-windowstyle-property-set-to-none/
this is the final solution
Known problems / bugs:
1. When resizing the arrow cursor appear instead of the resizing cursor.
2. Designer cant display the custom window.
3. When maximizing, randomly there's blue (the color of the borders) in big area of the screen - for split second
If you can fix any of the problems above it will be even better but I am satisfied with what I achieved.
EDIT:
Updated to allow resize modes (also added sample)
It's relatively easy to do this yourself... all you need to do is copy the Style that you see in the Metro UI, as you call it. To start you off, here is a very simple Style that changes the ControlTemplate of the Button elements to remove their default look:
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Of course, you'll want something to happen when the user moves their mouse pointer over the Button and you can do that by adding VisualStateManager.VisualStateGroups to the ControlTemplate. You can find a full example of this in the ControlTemplate Class page on MSDN.
The other controls Metro-style controls can be easily developed by creating simple ControlTemplates in the same way. Basically, you'll just need to remove the default WPF look and for the most part, just replace it with just a ContentPresenter as in the above example, or an ItemsPresenter for collection controls. Luckily the Metro look is very plain and simple, just remember to keep everything spaced out and plain.
To address another point you mad about resizing; you can set the Window.ResizeMode property to CanResizeWithGrip to add the resize grip in the bottom right corner of the Window as is often seen in these applications.

Binding to the UserControl Inside HierarchicalDataTemplate in Silverlight

I have customized TreeView in usercontrol.
In the HierarchicalDataTemplate I have an image with direction (arrow for the example).
When the application\UserControl flow direction change I need to flip the image.
So i tried binding the Image.FlowDirection (Which is flipping the image automatic when RightToLeft) to the UserControl.FlowDirection
<Image FlowDirection="{Binding Path=FlowDirection,
ElementName=MyUserControl}" ... />
But it is not working. I guess because he can't find the UserControl from inside the template.
I've tried this binding outside the template - and it's working fine.
Any solution ?
How can I get my UserControl from inside the template ?
--UPDATE--
There are two places of binding in this xaml. The first is in the style of the button, and it is working, and the second in the template of the TreeViewItem - and there it's not working.
<UserControl x:Class="MyTree"
...
d:DesignHeight="218" d:DesignWidth="284" x:Name="MyLayerListControl">
<UserControl.Resources>
<Style x:Key="CloseButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
...
</VisualStateManager.VisualStateGroups>
<Border x:Name="CloseButtonBorder" BorderThickness="0" Margin="3" CornerRadius="0" Background="Gray" >
<!-- THIS BINDING IS WORKING -->
<Image Source="{StaticResource back}" Margin="2"
FlowDirection="{Binding Path=FlowDirection, ElementName=MyLayerListControl}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent">
<Button Style="{StaticResource CloseButtonStyle}" />
<Grid>
<Grid.ColumnDefinitions></Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.Resources>
<sdk:HierarchicalDataTemplate x:Key="LayerListTemplate" ItemsSource="{Binding Path=Childrens}" >
<Grid>
<Border CornerRadius="2" BorderBrush="#FF6DBDD1" BorderThickness="1" Background="#FFBADDE9" Opacity="0.5" />
<StackPanel Orientation="Vertical">
<!-- The Item -->
<StackPanel Orientation="Horizontal" Margin="3">
<!-- THIS BINDING IS NOT WORKING -->
<Image x:Name="ArrowImage" Width="16" Height="16" Source="{StaticResource arrow}"
FlowDirection="{Binding Path=FlowDirection, ElementName=MyLayerListControl}"/>
</StackPanel>
</StackPanel>
</Grid>
</sdk:HierarchicalDataTemplate>
</Grid.Resources>
<sdk:TreeView ItemsSource="{Binding}" ItemTemplate="{StaticResource LayerListTemplate}" x:Name="MyTreeView" Grid.Row="1" />
</Grid>
</Grid>
</UserControl>
As #Chris says, add "DataContext" in front of you binding path, as you are binding to the Control itself, so if FlowDirection is a property of the DataContext, you need to have that.
Also, make sure you have Mode=TwoWay in your binding.
As an alternative, you can you use RelativeSource so you don't have to hard code an ElementName.
Check out: http://tonychampion.net/blog/index.php/2011/12/7th-day-of-silverlight-ancestor-relative-source-binding/

Resources