I created a grid with two buttons, i created an inner template for the first button; and button template in resources for the second one.
the problem is that i don't understand why the inner template don't show the content of the button ???
<Window x:Class="WpfTest.MainWindow"
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:WpfTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ControlTemplate x:Key="ButtonTemplate" TargetType="Button">
<Border BorderBrush="Orange" BorderThickness="3" CornerRadius="2" Background="Red" TextBlock.Foreground="White">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"/>
</Border>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="Button_A" >
<Button.Template>
<ControlTemplate >
<Border BorderBrush="Orange" BorderThickness="3" CornerRadius="2" Background="Red" TextBlock.Foreground="White">
<ContentPresenter ContentSource="Content" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"/>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button Grid.Column="1" Content="Button_B" Template="{StaticResource ButtonTemplate}">
</Button>
</Grid>
</Window>
Related
I am using the following ProgressBar Style:
<Style TargetType="{x:Type ProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ProgressBar}">
<Grid MinHeight="14" MinWidth="400" Background="{TemplateBinding Background}">
<Border x:Name="PART_Track" CornerRadius="2" BorderThickness="1">
<Border.BorderBrush>
<SolidColorBrush Color="#FFFFFF" />
</Border.BorderBrush>
</Border>
<Border x:Name="PART_Indicator" CornerRadius="2" BorderThickness="1" HorizontalAlignment="Left"
Background="{TemplateBinding Foreground}" Margin="0,-1,0,1">
<Grid ClipToBounds="True" x:Name="Animation">
<Rectangle x:Name="PART_GlowRect" Width="200" HorizontalAlignment="Left"
Fill="#3399FF" Margin="0,0,0,0" />
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="#404040"/>
</Style>
It's working fine but I want to display three rectangles with different colors at a time (Left, Center, Right) as the indicator part, how can I achieve this?
You should change your PART_GlowRect to be a Border instead of a Rectangle, and add the desired rectangles inside that:
<Border x:Name="PART_Indicator" CornerRadius="2" BorderThickness="1" HorizontalAlignment="Left"
Background="{TemplateBinding Foreground}" Margin="0,-1,0,1">
<Grid ClipToBounds="True" x:Name="Animation">
<Border x:Name="PART_GlowRect" Width="150" HorizontalAlignment="Left"
Background="Transparent" Margin="0,0,0,0" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Fill="Red" />
<Rectangle Grid.Column="1" Fill="Green" />
<Rectangle Grid.Column="2" Fill="Blue" />
</Grid>
</Border>
</Grid>
</Border>
This is how it will look like:
I know too little about design to pull this off.
I am trying to make a UserControl with a special border. The border should look like this:
The header is a label (or textblock if is a must) with the content set at init time.
The border must stop before the header and start again after the header with a margin like described.
The border will house a frame or grid which must confrom to the border shape (probably with a mask) The entire background must be transparent or alpha-ed (Color #000000XX) which is important because the header cant just "hide" the rectangle by being on top.
I'd appreciate directions to achieve this. Blend from visual studio 2012 is available.
Thank you
here you go
I made use of HeaderedContentControl which allows you to have a header and a content which you can further use in a template of your preference
<HeaderedContentControl x:Class="CSharpWPF.MyUserControl"
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"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
Header="Header">
<HeaderedContentControl.Template>
<ControlTemplate TargetType="HeaderedContentControl">
<Grid>
<Border BorderBrush="Black"
BorderThickness="4"
CornerRadius="10"
Padding="4"
Margin="10">
<ContentPresenter />
</Border>
<TextBlock Text="{TemplateBinding Header}"
Background="White"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="13"
Margin="25,0,0,0"
Padding="10,0"/>
</Grid>
</ControlTemplate>
</HeaderedContentControl.Template>
<Grid>
<TextBlock Text="content" />
</Grid>
</HeaderedContentControl>
result
Update
try this template, I did try to achieve by pure xaml
<HeaderedContentControl.Template>
<ControlTemplate TargetType="HeaderedContentControl">
<DockPanel x:Name="root"
LastChildFill="True"
Margin="10">
<DockPanel.Resources>
<Style TargetType="Border">
<Setter Property="BorderBrush"
Value="Black" />
<Setter Property="Width"
Value="30" />
<Setter Property="Height"
Value="30" />
<Setter Property="CornerRadius"
Value="10" />
</Style>
</DockPanel.Resources>
<Grid DockPanel.Dock="Top"
Height="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Border BorderThickness="4,4,0,0" />
<Border BorderThickness="0,4,0,0"
Grid.Column="2"
Width="auto"
CornerRadius="0" />
<Border BorderThickness="0,4,4,0"
Grid.Column="3"
HorizontalAlignment="Right" />
<TextBlock Text="{TemplateBinding Header}"
FontSize="13"
Grid.Column="1"
Margin="10,-10"
VerticalAlignment="Top" />
</Grid>
<Grid Height="20"
DockPanel.Dock="Bottom">
<Border BorderThickness="4,0,4,4"
Width="auto"
VerticalAlignment="Bottom" />
</Grid>
<Border BorderThickness="4,0,0,0"
DockPanel.Dock="Left"
Height="auto"
Width="20"
CornerRadius="0" />
<Border BorderThickness="0,0,4,0"
DockPanel.Dock="Right"
Width="20"
Height="auto"
CornerRadius="0" />
<ContentPresenter Margin="-10" />
</DockPanel>
</ControlTemplate>
</HeaderedContentControl.Template>
other approach might include some code behind if this is not suitable
result
I'm new to WPF,
I can't align the groupbox header text "abc" to the right,it's stays on the left, don't know why, can anyone help me please?
<Window x:Class="UserInterface.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="500" Width="625">
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="4*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1">
<GroupBox>
<GroupBox.Header>
<DockPanel>
<TextBlock HorizontalAlignment="Right">abc</TextBlock>
</DockPanel>
</GroupBox.Header>
</GroupBox>
</StackPanel>
</Grid>
</Grid>
</Window>
You have to override Template of Groupbox in case you want to align header to Right. By default it is placed at left in default template.
Key is to
Set Grid.ColumnSpan to 2 on border hosting Header ContentPresenter.
Set HorizontalAlignment to Right on ContentPresenter.
Here is the XAML which will work:
<GroupBox Header="abc">
<GroupBox.Template>
<ControlTemplate TargetType="GroupBox">
<Grid SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="6" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="6" />
</Grid.RowDefinitions>
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
CornerRadius="4,4,4,4"
BorderBrush="#00FFFFFF"
Background="{TemplateBinding Panel.Background}"
Grid.Column="0"
Grid.Row="1"
Grid.ColumnSpan="4"
Grid.RowSpan="3" />
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
CornerRadius="4,4,4,4"
BorderBrush="#FFFFFFFF"
OpacityMask="{x:Null}"
Grid.Row="1"
Grid.ColumnSpan="4"
Grid.RowSpan="3">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
CornerRadius="3,3,3,3"
BorderBrush="{TemplateBinding Border.BorderBrush}">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
CornerRadius="2,2,2,2"
BorderBrush="#FFFFFFFF" />
</Border>
</Border>
<Border Padding="3,1,3,0"
Name="Header"
Grid.Column="1"
Grid.ColumnSpan="2" <-- HERE
Grid.Row="0"
Grid.RowSpan="2">
<ContentPresenter RecognizesAccessKey="True"
HorizontalAlignment="Right" <-- And HERE
Content="{TemplateBinding HeaderedContentControl.Header}"
ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
ContentStringFormat="{TemplateBinding HeaderedContentControl.HeaderStringFormat}"
ContentSource="Header"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
Margin="{TemplateBinding Control.Padding}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
Grid.Column="1"
Grid.Row="2"
Grid.ColumnSpan="2" />
</Grid>
</ControlTemplate>
</GroupBox.Template>
</GroupBox>
You need to redesign the ContentPresenter inside the template of the Control.
MSDN has an example but somehow it also redesigns the GroupBox.
Check this out and see if thats what you are looking for. You are looking for this line
<ContentPresenter Margin="4"
ContentSource="Header"
RecognizesAccessKey="True" />
Just add to that:
HorizontalAlignment="Right"
I've created a WPF Custom Control, I put it on a form and give it a height and a width - all works fine. I'm referencing Height and Width using TemplateBinding in the control, so I need these to be set.
Should I decide to resize the control using the gui, the height and width disappear completely and the control formatting goes wrong.
How do I get the new height and width of the control and set it when this happens?
Posting code as requested:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GraphControls">
<Style TargetType="{x:Type local:ContourPlot}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ContourPlot}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Viewbox>
<Border BorderBrush="Black" BorderThickness="1">
<Canvas x:Name="cvGraph" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" >
<Rectangle Canvas.Left="40" Canvas.Top="31" Width="48" Height="41" Fill="AliceBlue"/>
</Canvas>
</Border>
</Viewbox>
<Canvas Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" >
<Label x:Name="lblTest" Canvas.Left="0" Canvas.Top="10" Content="Label" FontSize="12" />
</Canvas>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Control is used in a form as follows:
<Window x:Class="GraphWrapper.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gc="clr-namespace:GraphControls;assembly=GraphControls"
Title="MainWindow" Height="350" Width="525">
<Grid>
<gc:ContourPlot Background="#FFC3EAC3" Margin="65,42,128,118" Width="310" Height="150"/>
</Grid>
</Window>
As previously stated, when the control is resized via the gui, the Width and Height properties disappear.
<Style TargetType="{x:Type local:ContourPlot}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ContourPlot}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<Grid>
<Viewbox Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<Border BorderBrush="Black" BorderThickness="1">
<Canvas x:Name="cvGraph" >
<Rectangle Canvas.Left="40" Canvas.Top="31" Width="48" Height="41" Fill="AliceBlue"/>
</Canvas>
</Border>
</Viewbox>
<Canvas >
<Label x:Name="lblTest" Canvas.Left="0" Canvas.Top="10" Content="Label" FontSize="12" />
</Canvas>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
The Templated width and Height are not recommended to use in multiple controls inside its control Template. In Your case, Height and Width are going to be same as if you set like above.
More over you have placed the ViewBox and the Canvas in same area so its going to be overlap with same width and height. The problem might be with the Viewbox.
I am having a form in maximize mode, within the form contains a HeaderContentControl.
Within the HeaderContentControl.Content, i added a DockLayout, but the problem is that DockLayout is not fit to the form height.
How can I resolve this problem? Here's the xaml file:
<Window x:Class="Prototype.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Prototype"
Title="XXX"
x:Name="frmMain"
Width="581" Height="340" ResizeMode="CanMinimize"
WindowStartupLocation="CenterScreen" WindowState="Maximized"
WindowStyle="None" IsHitTestVisible="True" Topmost="False" AllowsTransparency="True" Background="Transparent" Loaded="frmMain_Loaded">
<!-- Copyright Microsoft Corporation. All Rights Reserved. -->
<Window.Resources>
<Style TargetType="{x:Type local:MainWindow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MainWindow}">
<Border Background="#FF333333"
BorderBrush="#FFCCCCCC"
BorderThickness="1"
CornerRadius="5"
Padding='2'>
<HeaderedContentControl>
<HeaderedContentControl.Header>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="19*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="212*" />
<ColumnDefinition Width="84*" />
<ColumnDefinition Width='Auto' />
</Grid.ColumnDefinitions>
<Rectangle Grid.ColumnSpan="3" Fill="#FF505050" />
<TextBlock FontSize="13"
FontWeight='Bold'
VerticalAlignment='Center'
Margin="6,5,3,6"
Text="XXX" Grid.ColumnSpan="2" OpacityMask="#FFCECECE" Foreground="#FFF3F3F3" Height="20" />
<Button x:Name='WindowCloseButton'
Grid.Column="2"
Width="17"
Height="17"
Cursor='Hand'
Margin="8,6,6,8"
VerticalAlignment='Center'
Click='WindowCloseButton_Click' FontFamily="Lucida Console">
<Button.Background>
<ImageBrush />
</Button.Background>
<Image Source="/Prototype;component/Resource/window-close.png"></Image>
</Button>
</Grid>
</HeaderedContentControl.Header>
<!-- New Content Area -->
<HeaderedContentControl.Content>
<ContentPresenter Content="{TemplateBinding Content}" />
</HeaderedContentControl.Content>
</HeaderedContentControl>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Foreground" Value="#FF7B7B7B"></Setter>
<Style.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Foreground" Value="#333333"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#333333"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="23" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Menu Height="23" Name="menuContext" Margin="0,0" Background="#FF7B7B7B" Foreground="White" Grid.Row="0">
<MenuItem Header="File" Background="#FF7B7B7B" Foreground="White">
<MenuItem Header="Open" Margin="0,1"/>
<MenuItem Header="Save" Margin="0,1"/>
<MenuItem Header="Exit" Margin="0,1" UseLayoutRounding="True" />
</MenuItem>
</Menu>
<Grid Grid.Row="1" ShowGridLines="True">
<DockPanel LastChildFill="True">
<Border Height="25"
Background="SkyBlue"
BorderBrush="Black"
BorderThickness="1"
DockPanel.Dock="Top">
<TextBlock Foreground="Black">Dock = "Top"</TextBlock>
</Border>
<Border Height="25"
Background="SkyBlue"
BorderBrush="Black"
BorderThickness="1"
DockPanel.Dock="Top">
<TextBlock Foreground="Black">Dock = "Top"</TextBlock>
</Border>
<Border Height="25"
Background="LemonChiffon"
BorderBrush="Black"
BorderThickness="1"
DockPanel.Dock="Bottom">
<TextBlock Foreground="Black">Dock = "Bottom"</TextBlock>
</Border>
<Border Width="200"
Background="PaleGreen"
BorderBrush="Black"
BorderThickness="1"
DockPanel.Dock="Left">
<TextBlock Foreground="Black">Dock = "Left"</TextBlock>
</Border>
<Border Background="White"
BorderBrush="Black"
BorderThickness="1">
<TextBlock Foreground="Black">This content will "Fill" the remaining space</TextBlock>
</Border>
</DockPanel>
</Grid>
</Grid>
</Window>
Problem here is HeaderedContentControl uses StackPanel internally to layout header and content.
To fix that, use a Grid instead or re-template HeaderedContentControl to use Grid.
Example:
<ControlTemplate TargetType="HeaderedContentControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentControl Content="{TemplateBinding Header}" Grid.Row="0" />
<ContentControl Content="{TemplateBinding Content}" Grid.Row="1" />
</Grid>
</ControlTemplate>
Adding a similar answer to the accepted one, but which uses a DockPanel instead of a Grid for a simpler implementation with the same results.
Example with DockPanel:
<ControlTemplate TargetType="HeaderedContentControl">
<DockPanel>
<ContentControl Content="{TemplateBinding Header}" DockPanel.Dock="Top" />
<ContentControl Content="{TemplateBinding Content}" />
</DockPanel>
</ControlTemplate>