How to handle conflicting Visual State Setters in separate Visual State Groups? - c#

Let's say I've got a RadioButton style defined in a XAML ResourceDictionary (no code-behind):
<Style x:Key="ExampleRadioButtonStyle"
TargetType="RadioButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid x:Name="Root">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<VisualState.Setters>
???
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="Content.Fill" Value="White" />
<Setter Target="Content.Stroke" Value="Blue" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked">
<VisualState.Setters>
<Setter Target="Content.Fill" Value="Transparent" />
<Setter Target="Content.Stroke" Value="Black" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse x:Name="Content"
StrokeThickness="5"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
Now I want to change the Content.Stroke property when the CommonStates.CurrentState is PointerOver to:
Cyan when the CheckStates.CurrentState is Checked
Gray when the CheckStates.CurrentState is Unchecked
What is the best way to achieve that?
Please note that this is just a simplified example prepared to present my problem which is much more complex in reality (for example I need to handle all CommonStates) so I look for a decent solution not a simple workaround handling only the mouse over behavior.

According to the code you provided, we can't directly get the selected state of the RadioButton from PointerOver.You can follow the native style,create two Ellipse,one for the selected state and the other for the unselected.Use the Check status switch to show or hideEllipse.Then set the stroke in PointerOver.For example:
<Ellipse x:Name="Content" Fill="{StaticResource RadioButtonOuterEllipseFill}" Height="20" StrokeThickness="{ThemeResource RadioButtonBorderThemeThickness}" Stroke="{ThemeResource RadioButtonOuterEllipseStroke}" UseLayoutRounding="False" Width="20"/>
<Ellipse x:Name="CheckedContent" Fill="{ThemeResource RadioButtonOuterEllipseCheckedFill}" Height="20" Opacity="0" StrokeThickness="{ThemeResource RadioButtonBorderThemeThickness}" Stroke="{ThemeResource RadioButtonOuterEllipseCheckedStroke}" UseLayoutRounding="False" Width="20"/>
When the CheckStates.CurrentState is Checked,you can show the CheckedContent and hide Content,the UnChecked the opposite.
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="Content.Opacity" Value="0"></Setter>
<Setter Target="CheckedContent.Opacity" Value="1"></Setter>
<Setter Target="CheckedContent.Fill" Value="White" />
<Setter Target="CheckedContent.Stroke" Value="Blue" />
</VisualState.Setters>
</VisualState>
......
</VisualStateGroup>
Then you can set stroke for different states in PointerOver.
<VisualState x:Name="PointerOver">
<VisualState.Setters>​
<Setter Target="Content.Stroke" Value="Gray"></Setter>​
<Setter Target="CheckedContent.Stroke" Value="Cyan"></Setter>​
</VisualState.Setters>​
</VisualState>

Related

Change background color on a selected Item in WPF with XAML [duplicate]

This question already has answers here:
Change background color for selected ListBox item
(7 answers)
Closed 9 days ago.
Basically, I want have a listBox and I want to change the color of the background and foreground of the item that I currently have selected.
I tried this:
<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Yellow"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FFAFA212"/>
</Trigger>
</Style.Triggers>
</Style>
But it didn't do anything at all. I tried searching for it but nothing i tried seemed to work, can anyone help please? This is an App.xaml in a c# project btw.
It's more complicated than you might imagine because of how wpf uses control templates to build controls.
The templates for a listbox and listboxitem is here:
https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/listbox-styles-and-templates?view=netframeworkdesktop-4.8
There are a number of ways you could accomplish this but I think the most informative would be to re template.
Here's something to take a look at. Put this in a parent control ( like the window or grid) resources:
<Style x:Key="{x:Type ListBoxItem}"
TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border"
Padding="2"
SnapsToDevicePixels="true">
<Border.Background>
<SolidColorBrush Color="Transparent" />
</Border.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected" />
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="Yellow" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="SelectedUnfocused">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="Yellow" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="#FFAFA212" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Note that only one visual group can apply at a time and the last one wins.
There are subtleties to this.
See the line
<VisualState x:Name="Normal"/>
Remove that and see what happens

UWP Gridviewitem hover border is not shaped

I'm having a simple GridView which its items have corner radius.
The presentation of the items is fine, but when hovering with the mouse the corner radius is not applied and it doesn't look good.
in the example above, item B2.
I'd like to keep the reveal effect when hovering.
this is my code:
<Page.Resources>
<DataTemplate x:Key="PersonDataTemplate" x:DataType="local:Person">
<Border
Width="200"
Height="50"
Background="AliceBlue"
BorderBrush="#D0D0D0"
BorderThickness="1"
CornerRadius="90">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{x:Bind FullName}" />
</Border>
</DataTemplate>
</Page.Resources>
<Grid Padding="64">
<GridView ItemTemplate="{StaticResource PersonDataTemplate}" ItemsSource="{x:Bind Persons, Mode=OneWay}" />
</Grid>
how can I implement that?
UWP Gridviewitem hover border is not shaped
The pointer hove rectangle like the above screenshot is GridViewItem's ListViewItemPresenter style. if you want to remove them, you could custom GridViewItem style and set the related part as Transparent. And you could use the following style directly.
<Style x:Key="GridViewItemRevealStyle" TargetType="GridViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Background" Value="{ThemeResource GridViewItemBackground}" />
<Setter Property="Foreground" Value="{ThemeResource GridViewItemForeground}" />
<Setter Property="TabNavigation" Value="Local" />
<Setter Property="IsHoldingEnabled" Value="True" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Margin" Value="0,0,4,4" />
<Setter Property="MinWidth" Value="{ThemeResource GridViewItemMinWidth}" />
<Setter Property="MinHeight" Value="{ThemeResource GridViewItemMinHeight}" />
<Setter Property="AllowDrop" Value="False" />
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="-2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewItem">
<ListViewItemPresenter
x:Name="Root"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
CheckBoxBrush="{ThemeResource GridViewItemCheckBoxBrush}"
CheckBrush="{ThemeResource GridViewItemCheckBrush}"
CheckMode="{ThemeResource GridViewItemCheckMode}"
ContentMargin="{TemplateBinding Padding}"
ContentTransitions="{TemplateBinding ContentTransitions}"
Control.IsTemplateFocusTarget="True"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
DragBackground="{ThemeResource GridViewItemDragBackground}"
DragForeground="{ThemeResource GridViewItemDragForeground}"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
FocusBorderBrush="{ThemeResource GridViewItemFocusBorderBrush}"
FocusSecondaryBorderBrush="{ThemeResource GridViewItemFocusSecondaryBorderBrush}"
FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
PlaceholderBackground="{ThemeResource GridViewItemPlaceholderBackground}"
PointerOverBackground="Transparent"
PointerOverForeground="{ThemeResource GridViewItemForegroundPointerOver}"
PressedBackground="{ThemeResource GridViewItemBackgroundPressed}"
ReorderHintOffset="{ThemeResource GridViewItemReorderHintThemeOffset}"
RevealBackground="{ThemeResource GridViewItemRevealBackground}"
RevealBorderBrush="{ThemeResource GridViewItemRevealBorderBrush}"
RevealBorderThickness="{ThemeResource GridViewItemRevealBorderThemeThickness}"
SelectedBackground="Transparent"
SelectedForeground="{ThemeResource GridViewItemForegroundSelected}"
SelectedPointerOverBackground="Transparent"
SelectedPressedBackground="{ThemeResource GridViewItemBackgroundSelectedPressed}"
SelectionCheckMarkVisualEnabled="{ThemeResource GridViewItemSelectionCheckMarkVisualEnabled}"
>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected" />
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="PointerOver" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverSelected">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="PointerOver" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverPressed">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PressedSelected">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="Root.RevealBorderThickness" Value="0" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ListViewItemPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style
x:Key="GridViewItemContainerStyle1"
BasedOn="{StaticResource GridViewItemRevealStyle}"
TargetType="GridViewItem"
/>
Usage
<Grid Padding="64">
<GridView
IsTabStop="False"
ItemContainerStyle="{StaticResource GridViewItemContainerStyle1}"
ItemTemplate="{StaticResource PersonDataTemplate}"
/>
</Grid>
That’s because the hover border of the GridViewItem is defined in its Style!
By setting the DataTemplate, you are only setting the content of the GridViewItem, without modifying the presenting Style of the control itself!
You need to create a new Style, inherited from the default one from the GridViewItem and, from there, customizing the hover border and all the properties of the “box” that presents the “content”.
Regards

WPF: Styling radio buttons into a square

I have a WPF application where I need the user to pick one and only one corner of an onscreen box.
It makes sense to me that the type of button would be a radio button. Exactly one corner can be selected at a time.
But, Radio buttons are naturally round in Windows and WPF. But WPF allows someone to restyle the UI elements, if they understand how.
Can someone show me how this could be restyled. I would like to see it done in a way that would not affect the look of the other radio buttons in the same window.
To style the RadioButton the way you want it, you'll need to change its ControlTemplate to a custom one. This link has a sample ControlTemplate. I've adapted it so that the RadioButton shows up as a square. It's a simplified ControlTemplate in that it has no animations:
<Style x:Key="SquareRadioButton" TargetType="{x:Type RadioButton}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource RadioButtonFocusVisual}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Grid Width="13" Height="13">
<Rectangle
x:Name="Border"
StrokeThickness="1"
Stroke="Black"
Fill="White"
/>
<Rectangle
x:Name="CheckMark"
Fill="Black"
Visibility="Collapsed"
Margin="2"
/>
</Grid>
</BulletDecorator.Bullet>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Pressed" />
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="Border"
Storyboard.TargetProperty="Stroke.Color"
>
<DiscreteColorKeyFrame KeyTime="0" Value="LightGray" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="Fill.Color"
>
<DiscreteColorKeyFrame KeyTime="0" Value="LightGray" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked" >
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="(UIElement.Visibility)"
>
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter
Margin="4,0,0,0"
VerticalAlignment="Center"
HorizontalAlignment="Left"
RecognizesAccessKey="True"
/>
</BulletDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You can then apply it to the RadioButton you want to style:
<RadioButton Style="{StaticResource SquareRadioButton}" Content="Option 1" />

How to keep the ToggleButton status after re-enable

I want to keep the ToggleButton status after re-enable the ToggleButton.But It keep turning off.
Here is my ToggleButton when the Ellipse is actived:
When the ToggleLock is turned on:
After unlocking:
It's wrong color.It have to turn to green color.
My code and Style:
<!--EllipseToggleButton Style-->
<Style TargetType="ToggleButton"
x:Key="EllipseToggleButton">
<Setter Property="Margin"
Value="20 10 0 10" />
<Setter Property="Height"
Value="30" />
<Setter Property="VerticalAlignment"
Value="Top" />
<Setter Property="IsTabStop"
Value="False" />
<Setter Property="FocusVisualStyle"
Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid Name="contain">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimation Storyboard.TargetName="icon"
Storyboard.TargetProperty="(Path.Fill).(Color)"
To="#3D727272"
Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckedStates">
<VisualState x:Name="Checked">
<Storyboard>
<ColorAnimation x:Name="IconCheckedColorAni"
Storyboard.TargetName="icon" Duration="0"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#FF68E80F" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse Name="icon"
Height="24"
Width="24"
Stretch="Uniform"
VerticalAlignment="Center"
Cursor="Hand"
Fill="{TemplateBinding Background}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
MainWindow:
<StackPanel Orientation="Horizontal">
<ToggleButton x:Name="ToggleLock"
Content="Lock"
Width="100"
Margin="20 10 0 10"
VerticalAlignment="Top"
Height="30" />
<ToggleButton Style="{StaticResource EllipseToggleButton}"
IsEnabled="{Binding ElementName=ToggleLock, Path=IsChecked, Converter={StaticResource InBConv}}"
Background="Red" />
</StackPanel>
Converter:
class InvertBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && value is bool)
{
return !(bool)value;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
The ToggleButton does retain its IsChecked value while it is disabled. When it is re-enabled, however, the visuals don't match: When you un-toggle the lock, you activate the CommonStates.Normal visual state group, which, near as I can tell, resets the default value on the Ellipse named icon :
Fill="{TemplateBinding Background}"
...making it red. You'll find you need to click the ellipsis twice in order to make it green again.
Since the ellipsis toggle button doesn't change its IsChecked value, the CheckedStates visual state storyboards aren't invoked.
I haven't found any way to fix this in XAML (tried reordering triggers, writing out all states explicitly and so on), but you can work around it by forcing an IsChecked state change from code-behind:
<StackPanel Orientation="Horizontal">
<ToggleButton x:Name="ToggleLock"
Content="Lock"
Width="100"
Margin="20 10 0 10"
VerticalAlignment="Top"
Height="30"
Checked="OnChecked"
Unchecked="OnChecked" />
<ToggleButton
x:Name="toggleButton"
Style="{StaticResource EllipseToggleButton}"
IsEnabled="{Binding ElementName=ToggleLock, Path=IsChecked, Converter={StaticResource InBConv}}"
Background="Red" />
</StackPanel>
...with the following event handler:
private void OnChecked(object sender, RoutedEventArgs e)
{
bool? isChecked = this.toggleButton.IsChecked;
toggleButton.IsChecked = null;
toggleButton.IsChecked = isChecked;
}
I don't know that this is the best possible solution, but it does work, and may serve as a starting point for further investigation.
I think the source of your problem is using the same element for 2 different VisualStateGroup. As you can see here there is an element named "DisabledVisualElement" to handle "Disabled" VisualState that is separate from the element that handles "CheckStates" VisualStateGroup.
Following that, I added another ellipse named "iconDisabled" to the template that has Opacity="0" and its value changes to "1" in "Disabled" VisualState. Also, I added Opacity="1" to your "icon" and it will change to "0" in "Disabled" VisualState.
Here is your modified style code:
<Style TargetType="ToggleButton"
x:Key="EllipseToggleButton">
<Setter Property="Margin"
Value="20 10 0 10" />
<Setter Property="Height"
Value="30" />
<Setter Property="VerticalAlignment"
Value="Top" />
<Setter Property="IsTabStop"
Value="False" />
<Setter Property="FocusVisualStyle"
Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid Name="contain">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0"
Storyboard.TargetName="iconDisable"
Storyboard.TargetProperty="Opacity" To="1" />
<DoubleAnimation Duration="0"
Storyboard.TargetName="icon"
Storyboard.TargetProperty="Opacity" To="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckedStates">
<VisualState x:Name="Checked">
<Storyboard>
<ColorAnimation x:Name="IconCheckedColorAni"
Storyboard.TargetName="icon" Duration="0"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#FF68E80F" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked">
<Storyboard>
<ColorAnimation x:Name="IconUncheckedColorAni"
Storyboard.TargetName="icon" Duration="0"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="Red" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse Name="icon"
Height="24"
Width="24"
Opacity="1"
Stretch="Uniform"
VerticalAlignment="Center"
Cursor="Hand"
Fill="{TemplateBinding Background}" />
<Ellipse Name="iconDisable"
Height="24"
Width="24"
Opacity="0"
Stretch="Uniform"
VerticalAlignment="Center"
Cursor="Hand"
Fill="#3D727272" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Other parts of the code are the same as you wrote in question post.
I'm using IsHitTestVisible instead of IsEnabled.
Here is the way I fixed my issue:
<ToggleButton x:Name="ToggleLock"
IsChecked="{Binding OptionLocked}"
Content="Lock"
Width="100"
Margin="20 10 0 10"
VerticalAlignment="Top"
Height="30" />
<ToggleButton x:Name="toggleButton"
IsChecked="{Binding EllipseChecked}"
Style="{StaticResource EllipseToggleButton}"
IsHitTestVisible ="{Binding OptionLocked, Converter={StaticResource InvertBoolConv}}"/>
I having another issue.I can't set background color to Gray when the ToggleLock is turning on.At least it's working.I will accept it if no more answer come in a few days.
I want to say thank Petter Hesselberg and TheSETJ.
Finally I have fixed it.Here is a new ControlTemplate:
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled" />
</VisualStateGroup>
<VisualStateGroup x:Name="CheckedStates">
<VisualState x:Name="Checked">
<Storyboard>
<ColorAnimation x:Name="IconCheckedColorAni"
Storyboard.TargetName="icon"
Duration="0"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse Name="icon"
Height="24"
Width="24"
Stretch="Uniform"
VerticalAlignment="Center"
Cursor="Hand"
Fill="{TemplateBinding Background}"
Visibility="Visible" />
<Ellipse Name="iconDisable"
Height="24"
Width="24"
Stretch="Uniform"
VerticalAlignment="Center"
Cursor="Hand"
IsHitTestVisible="{TemplateBinding IsHitTestVisible}"
Fill="3D727272"
Visibility="Collapsed" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsHitTestVisible">
<Trigger.Value>
<sys:Boolean>False</sys:Boolean>
</Trigger.Value>
<Setter TargetName="iconDisable"
Property="Visibility"
Value="Visible" />
<Setter TargetName="icon"
Property="Visibility"
Value="Collapsed" />
</Trigger>
<Trigger Property="IsHitTestVisible">
<Trigger.Value>
<sys:Boolean>True</sys:Boolean>
</Trigger.Value>
<Setter TargetName="iconDisable"
Property="Visibility"
Value="Collapsed" />
<Setter TargetName="icon"
Property="Visibility"
Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
And MainWindow.xaml:
<ToggleButton x:Name="ToggleLock"
IsChecked="{Binding OptionLocked}"
Content="Lock"
Width="100"
Margin="20 10 0 10"
VerticalAlignment="Top"
Height="30" />
<ToggleButton x:Name="toggleButton"
IsChecked="{Binding EllipseChecked}"
Style="{StaticResource EllipseToggleButton}"
IsHitTestVisible ="{Binding OptionLocked, Converter={StaticResource InvertBoolConv}}"/>

Rounded Buttons in XAML for a window store app

This seemed to me a really simple question 2 hours ago, but haven't made any progress with it.
My first search last night, said to create a rounded button, you just put it in a border, and round the edges of the border, like this,,,
<Border BorderThickness="1"
BorderBrush="Black"
CornerRadius="10"
Padding="4"
Background="#FFB8B1B1"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Button Width="45"
Height="35"
Name="GetFileName"
VerticalAlignment="Top"
VerticalContentAlignment="Top"
BorderThickness="0"
FontSize="16"
Foreground="Black"
Tapped="GetFileName_Tapped"
Background="#FFB8B1B1">Pick</Button>
</Border>
This looks good, but I wanted one thing to look better. When you hover over the button the background changes color, but not the background of the border. To achieve this second part has stumped me. Any leads would be appreciated. Thanks, John.
One possibility is to use ControlTemplate and VisualStateManager
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="1"
x:Name="MBorder"
BorderBrush="Black"
CornerRadius="10"
Padding="4">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Target="MGrid.Background" Value="#FFB8B1B1"/>
<Setter Target="MBorder.Background" Value="#FFB8B1B1"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="MGrid.Background" Value="Green"/>
<Setter Target="MBorder.Background" Value="Green"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="MGrid.Background" Value="Blue"/>
<Setter Target="MBorder.Background" Value="Blue"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="MGrid">
<ContentControl Content="{TemplateBinding Content}"
VerticalContentAlignment="Center"
HorizontalAlignment="Center"
FontSize="{TemplateBinding FontSize}"
Foreground="{TemplateBinding Foreground}"/>
</Grid>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
I used #Mihkel 's Answer to solve this. However, his answer misses the key ingredient, that being the background of the border. I named the border in the control, as well as set a Template binding in the border. Then referenced that, as well as the background of the button. I am trying to put the changes in bold, but they just appear as **, the code encased in the stars is the changes.
<Button Content="Pick"
Width="45"
Height="35"
VerticalAlignment="Center"
HorizontalAlignment="Center"
BorderThickness="0"
FontSize="16"
Foreground="Black"
Tapped="GetFileName_Tapped"
Background="#FFB8B1B1">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="1"
BorderBrush="Green"
CornerRadius="10"
Padding="4"
**Background="{TemplateBinding Background}"**
Name="TheBorder"
>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Target="MGrid.Background" Value="#FFB8B1B1"/>
**<Setter Target="TheBorder.Background" Value="#FFB8B1B1" />**
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="MGrid.Background" Value="Green"/>
**<Setter Target="TheBorder.Background" Value="Green" />**
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="MGrid.Background" Value="Blue"/>
**<Setter Target="TheBorder.Background" Value="Blue" />**
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="MGrid">
<ContentControl Content="{TemplateBinding Content}"
VerticalContentAlignment="Center"
HorizontalAlignment="Center"
FontSize="{TemplateBinding FontSize}"
Foreground="{TemplateBinding Foreground}"
Background="{TemplateBinding Background}"/>
</Grid>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
Of note, this is going to be used in an open source project called Essential Video Editor. An early version is in the windows store. The source code is in GitHub.com/gibbloggen And, when I publish this part, I will credit this post, in way of a reference.

Categories