xaml border style - wpf

I create style for buttons:
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#8A88E1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It all OK. Now I want to write part of the style that would be looked around the ellipse boundary.

Erno beat me to the answer, but here's an example:
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#8A88E1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}" Stroke="..." StrokeThickness="..." />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You should be able to bind the Stroke to the parent BorderBrush but I haven't tested it: Stroke="{TemplateBinding BorderBrush}". However, you won't be able to directly bind StrokeThickness to the parent BorderThickness as they're two different types (Ellipse.StrokeThickness is uniform and a simple double value whereas Button.BorderThickness is of type Thickness.).

There are two options:
Set the Stroke and StrokeThickness of the ellipse or
Add a template to the border and use an ellipse in the template.
Let me know if you need help with these.

Related

Without border style doesn't place the text in the center of a WPF button

I have the following style that hides or makes invisible at the border of a button:
<Style x:Key="SinBorde" TargetType="{x:Type Button}" >
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="Transparent">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And the button looks like the one on the left of the next image, notice the button on the right that doesn't have that style applied and the text is in the middle of the button:
Any comments or suggestions how to center text are welcome
default Button template sets alignment for content:
<Style x:Key="SinBorde" TargetType="{x:Type Button}" >
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="Transparent">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How to change the background of a GridSplitter when focused/dragged in XAML (with a border)?

I found it weird that there's no GridSplitter property like "DragBackground" or something alike.
This seems to work though:
<UserControl.Resources>
<Style x:Key="CustomGridSplitterStyle" TargetType="GridSplitter">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridSplitter">
<Grid x:Name="Root" >
<!-- Background -->
<Rectangle Fill="White" StrokeThickness="0" />
<!-- Focus Visual -->
<Rectangle x:Name="FocusVisual" Stroke="White" StrokeThickness="1" Opacity="0" IsHitTestVisible="false" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
 
GridSplitter Style="{StaticResource CustomGridSplitterStyle}" Grid.Column="1" Width="6" HorizontalAlignment="Stretch"
BorderThickness="2,0,0,0" BorderBrush="Blue" />
My problem with this solution however is that I'd like to set a border on the left side of the GridSplitter (see above), which doesn't work when using the custom GridSplitter style.
Does anybody know how to get this working ?
If you want to use BorderBrush and BorderThickness in your Template you can use TemplateBinding on some Border. You can also use Setter in your Style to define some default value.
<Style x:Key="CustomGridSplitterStyle" TargetType="{x:Type GridSplitter}">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridSplitter">
<Border
x:Name="FocusVisual"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"/>
<ControlTemplate.Triggers>
<Trigger Property="IsDragging" Value="True">
<Setter TargetName="FocusVisual" Property="..." Value="..." />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Also since GridSplitter is a Thumb and as such has IsDragging property so you can create Trigger to do something when it is true as in the example above

Naming Control Contained Within Custom WPF GroupBox

I've got a custom GroupBox control that essentially does nothing more than apply a style
<GroupBox x:Class="SharedResources.Controls.StyledGroupBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<GroupBox.Style>
<Style TargetType="{x:Type GroupBox}">
<Setter Property="BorderBrush" Value="#D5DFE5"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">
...
<ContentPresenter Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="2"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupBox.Style>
</GroupBox>
The problem is that when I come to use this, if I set x:Name property of the content of the StyledGroupBox, then I get the following error:
Cannot set Name attribute value 'name' on element ''. '' is under the scope of element 'StyledGroupBox', which already had a name registered when it was defined in another scope
Any ideas how I can resolve this?
Don't use a UserControl just to define a Style (I'd love to know where this practice comes from because I've seen an explosion of it recently). Instead, create the Style as a resource in its own right and apply it to GroupBoxes as desired:
<Style TargetType="{x:Type GroupBox}">
<Setter Property="BorderBrush" Value="#D5DFE5"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">...
<ContentPresenter Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="2" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
...
<GroupBox>
Will inherit the above style.
</GroupBox>
If anyone is trying to make this work (for something more/other than styles), see: How to create a WPF UserControl with NAMED content

How do I set the height of a wpf slider control's thumb

I want to put a slider in a datagrid cell and the row has a height of 20, so i'd like to make the height of the thumb of the slider smaller than that. I set the height of the slider itself, but the thumb appears to be cut off (i.e. it doesn't scale down to the height that I specify in the slider.height property). I don't want to have to override the entire control template of the slider control to do this. There's got to be some way of setting a property or something like that.
Edit: Even when I create a custom slider style which includes the custom thumb style with the sizes I want, it still doesn't size right.
Any ideas?
<Slider.LayoutTransform>
<ScaleTransform ScaleY="0.9" CenterX="15" CenterY="15"/>
</Slider.LayoutTransform>
Not very sexy, but it works like a charm when combined whith the Slider.Height/Slider.Width properties !
Set thumb style:
<Style x:Key="SliderThumbStyle" TargetType="{x:Type Thumb}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<!--<Ellipse
Name="Ellipse"
Fill="Yellow"
Stroke="Yellow"
Height="10"
Width="{Binding Path=ThumbWidth, RelativeSource={RelativeSource TemplatedParent}}"
StrokeThickness="1" />-->
<Rectangle
Fill="Azure"
Stroke="Azure"
Height="7"
Width="{Binding Path=ThumbWidth, RelativeSource={RelativeSource TemplatedParent}}"
StrokeThickness="1"
Margin="0.1,.1,.1,.1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then use this style slider custom control
<Style TargetType="{x:Type local:NvSliderControl}">
<Setter Property="Orientation" Value="Vertical" />
<Setter Property="Height" Value="50"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:NvSliderControl}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Track x:Name="PART_Track" >
<Track.Thumb>
<Thumb Style="{StaticResource SliderThumbStyle}">
</Thumb>
</Track.Thumb>
</Track>
</Grid>
</Border>
<ControlTemplate.Triggers>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF Template Inheritance

I created a button. My basic requirements are rounded thicker border, with more than one color (i.e. for Buy/Sell buttons)
I was hoping that i could create the template once, and than just override the border brush like this:
<Style x:Key="BorderButton">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderThickness="2"
BorderBrush="Red"
CornerRadius="3"
Background="{x:Null}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="GreenBorderButton" BasedOn="{StaticResource BorderButton}" TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="Green" />
</Style>
but they both produce the same style.
Do i need to write out the whole template every time? seems like unnecessary code repetition (especially if 3-4 colors are desired). Hoping there is some way to inherit a template.
Your code is very close to working; the issue is that GreenBorderButton is applying the BorderBrush to the button itself, not the Border in the overridden Template.
To fix this, simply change the Border's BorderBrush to use the parent Button's BorderBrush. You can do this using a TemplateBinding like so:
<Style x:Key="BorderButton">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border"
BorderThickness="2"
BorderBrush="{TemplateBinding Property=BorderBrush}"
CornerRadius="3"
Background="{x:Null}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then, you can either use the same overridden styles like you have, or you could simply do:
<Button Style="{StaticResource BorderButton}" BorderBrush="Blue" Content="Blue" />

Resources