WPF Style Sheets and Bindings - wpf

I have a style sheet that i want to be used on different custom controls.
Example
Stylesheet.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="ExampleProgressBar" TargetType="ProgressBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border DataContext="{Binding RelativeSource={RelativeSource Self}}" Background="{Binding Path=Example_BG}">
<Grid x:Name="PART_Track" >
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left" Fill="#FF1B9AF1" RadiusX="5" RadiusY="5"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
When I use something like above on the style sheet it doesn't bind to the custom control....
Is there anyway to bind stylesheet styles to work with many custom controls?

Related

WPF Change style of System ContextMenu

Is it possible to style the System ContextMenu?
If it does, I would appreciate if you could tell me how..
I want to change its style, not to add items/disable items.
I am talking about this:
EDIT:
This is the style I am using right now (this is just an example - to see if it's possible to style the system ContextMenu:
<Style TargetType="{x:Type ContextMenu}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Grid Margin="0,0,5,5">
<Border x:Name="SubMenuBorder" BorderBrush="Red" BorderThickness="1" Background="Yellow" SnapsToDevicePixels="True" Padding="2">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
<Border.Effect>
<DropShadowEffect Color="{StaticResource DropShadowColor}" Opacity="0.60" ShadowDepth="3"/>
</Border.Effect>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The style is located in the App.xaml file - it affect all the ContextMenus in my app except the System ContextMenu

How can I style certain WPF listboxes to be radio buttons?

I want to style some of my listboxes' items to be radiobuttons. Here is the code I have but this style gets applied to every listboxitem.
<Window.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<RadioButton Content="{TemplateBinding Content}"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
How can I do something so I can designate a listbox to have radio buttons. I imagine the designation would go something like this:
<ListBox Name="ListBox1" Width="120" Visibility="Visible" Background="{x:Null}" BorderThickness="0" Style="{StaticResource radioListBox}">
I know part of the problem is that this only styles listboxitems but I am not sure how to style the listbox itself. I would of course prefer to add in the background and border properties.
Any help would be appreciated.
You need to give your Style a key:
<Window.Resources>
<Style x:Key="radioListBoxItem" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<RadioButton Content="{TemplateBinding Content}"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
And then you would apply it to a ListBox like:
<ListBox ItemContainerStyle="{StaticResource radioListBoxItem}" />
If you want to create a style for a ListBox that contains the radio list box items, and some other properties, you could do that too:
<Style x:Key="radioListBox" TargetType="{x:Type ListBox}">
<Setter Property="ItemContainerStyle" Setter="{StaticResource radioListBoxItem}" />
<Setter Property="Background" Value="Navy" />
</Style>
And you'd apply it:
<ListBox Style="{StaticResource radioListBox}" />

Parameterized style/template in WPF?

If I have two 200 lines long control templates which differ only in a few words (a few colors), how can I make the xaml reusable ? That is, to don't have to copy-paste the template and change 3 words in 200 lines.
Here is a simplified example. The only difference between the two styles is the border color. So can I somehow define a ButtonStyle, with a parameterized color, and inherit BlackButtonStyle and GrayButtonStyle from it, and specify only that color in BlackButtonStyle and GrayButtonStyle ?
<Window x:Class="WpfApplication33.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style x:Key="BlackButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="Black" BorderThickness="3">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="GrayButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="Gray" BorderThickness="3">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<Button Content="Black Button"
Style="{StaticResource BlackButtonStyle}"/>
<Button Content="Gray Button"
Style="{StaticResource GrayButtonStyle}"/>
</StackPanel>
</Window>
Here is the code based on the 2 answers. Only a style needs to be set on the control, but unfortunately it still messes up the Tag of the control:
<Window x:Class="WpfApplication33.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="border"
BorderBrush="Black"
BorderThickness="3">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Tag" Value="Gray">
<Setter TargetName="border"
Property="BorderBrush"
Value="Gray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BlackButtonStyle"
TargetType="{x:Type Button}"
BasedOn="{StaticResource ButtonStyle}"/>
<Style x:Key="GrayButtonStyle"
TargetType="{x:Type Button}"
BasedOn="{StaticResource ButtonStyle}">
<Setter Property="Tag" Value="Gray"/>
</Style>
</Window.Resources>
<StackPanel>
<Button Content="Black Button"
Style="{StaticResource BlackButtonStyle}"/>
<Button Content="Gray Button"
Style="{StaticResource GrayButtonStyle}"/>
</StackPanel>
</Window>
While Charlie's right about his example, for your specific case I'd just use the BorderThickness and BorderBrush properties that a button already exposes: you can use {TemplateBinding BorderBrush} instead of creating your own property.
Edit: sample xaml... note that my style defaults the color & thickness, but these could be overridden inline...
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Page.Resources>
<SolidColorBrush x:Key="BlackBrush" Color="Black"/>
<SolidColorBrush x:Key="GrayBrush" Color="Gray"/>
<Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}">
<Setter Property="BorderThickness" Value="3" />
<Setter Property="BorderBrush" Value="{StaticResource BlackBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderColor="{TemplateBinding BorderThickness}">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<StackPanel>
<Button Content="Black Button" BorderBrush="{StaticResource BlackBrush}"
Style="{StaticResource CustomButtonStyle}"/>
<Button Content="Gray Button" BorderBrush="{StaticResource GrayBrush}"
Style="{StaticResource CustomButtonStyle}"/>
</StackPanel>
The right way to go about this is usually to create a DependencyProperty on the class that can hold the parametrized data, and then bind to that property in your template. For the sake of creating a quick example, I'm going to use the Button.Tag property, which works perfectly well for storing something as simple as a brush:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Page.Resources>
<SolidColorBrush x:Key="BlackBrush" Color="Black"/>
<SolidColorBrush x:Key="GrayBrush" Color="Gray"/>
<Style x:Key="CustomButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="{TemplateBinding Tag}" BorderThickness="3">
<ContentControl Content="{TemplateBinding Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<StackPanel>
<Button Content="Black Button" Tag="{StaticResource BlackBrush}"
Style="{StaticResource CustomButtonStyle}"/>
<Button Content="Gray Button" Tag="{StaticResource GrayBrush}"
Style="{StaticResource CustomButtonStyle}"/>
</StackPanel>
Have a look at this solution, it solves the exact issue you're having.

wpf textbox flat border style

need to have flat border style for wpf based textbox... really surprised to see there is no easy way to get this like was in winforms textbox BorderStyle.FixedSingle
is there any easy way to get this done for wpf textbox
The way to do this is to use a control template to draw the border yourself. You can do this in many different ways, heres a couple for you to look at.
The quick hack approach:
<TextBox>
<TextBox.Template>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Rectangle Stroke="{StaticResource ResourceKey=detailMarkBrush}" StrokeThickness="1"/>
<TextBox Margin="1" Text="{TemplateBinding Text}" BorderThickness="0"/>
</Grid>
</ControlTemplate>
</TextBox.Template>
</TextBox>
and then theres using resources...
<ResourceDictionary>
<Color x:Key="detailMark">#FFA1A9B3</Color>
<SolidColorBrush x:Key="detailMarkBrush" Color="{StaticResource ResourceKey=detailMark}" />
<Style x:Key="flatTextBox" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Rectangle Stroke="{StaticResource ResourceKey=detailMarkBrush}" StrokeThickness="1"/>
<TextBox Margin="1" Text="{TemplateBinding Text}" BorderThickness="0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
and then you can use the style:
<TextBox Style="{StaticResource ResourceKey=flatTextBox}" />
<TextBox BorderThickness="1" BorderBrush="Black">
just try this by black or gray
This is better way to me, make a custom template with border, to override the default one.
And most important make ScrollViewer named PART_ContentHost, to fit inner TemplatePart, and for any other features work like default.
simular to example from MSDN:
<Style TargetType="TextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border CornerRadius="2" Padding="2" Background="#19212F" BorderBrush="Red" BorderThickness="1">
<ScrollViewer Margin="0" x:Name="PART_ContentHost" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How do I create a Style within a WPF UserControl?

I want to set the style of some controls on my UserControl, but can't seem to find the right syntax:
<UserControl x:Class="HiideSRM.WIDSModule.BiometricStatusIndicator"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Style TargetType="{x:Type Border}">
<Setter Property="Width" Value="10"/>
</Style>
<StackPanel Orientation="Horizontal" x:Name="Panel">
<Border Height="50" Margin="1"/>
<Border Height="10" Margin="1"/>
<Border Height="10" Margin="1"/>
<Border Height="10" Margin="1"/>
</StackPanel>
</UserControl>
first, place your styles into a .Resources tag--which can be the child of pretty much any control tag (eg. border, usercontrol, grid, etc.)
second, you can specify the style in the tag, but since you didnt declare an x:key on your resource, the style will apply to ALL borders in this control.
<UserControl.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="Width" Value="10"/>
</Style>
</UserControl.Resources>
note that the syntax is different for silverlight. instead of TargetType="{x:Type Border}" you would use TargetType="Border"

Resources