This project is read-only.

ToggleButton style

May 2, 2013 at 5:19 AM
Hi,
First of all I want to say: 'Great Job!!! Thanks a lot'

My question is: is it ToggleButton in the library or should I create my own? If it's not there will it be included soon or later?

Thanks.
May 2, 2013 at 1:46 PM
A ToggleButton is not included, feel free to create an issue for it in the issue tracker
Jul 2, 2013 at 9:17 PM
Hello, poborin, did you have sucess in creating the custom ToggleButton style? I'm very interested in it, I've tried to do it by my own but it seems to require to create a .cs file with the .xaml for the DependecyProperties for the icon and it's size. I've been struggling all day but I can't figure out how to do it. Could you give me a piece of advice? Thanks!
Jul 3, 2013 at 1:29 AM
Hi everytimer,

I've end up with no ToggleButton in my current UI design, so I don't have a cooked solution, but it's a quite a straight forward task. Let me show you an example:
  • Create a .cs file with DependecyProperties, in my case it was a:
public class ResizebleModernButton : ModernButton
    {
        public static readonly DependencyProperty RadiusProperty =
            DependencyProperty.Register("Radius", typeof(double), typeof(ResizebleModernButton));

        public double Radius
        {
            get { return (double)GetValue(RadiusProperty); }
            set { SetValue(RadiusProperty, value); }
        }

        static ResizebleModernButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ResizebleModernButton), new FrameworkPropertyMetadata(typeof(ToggleTile)));
        }
    }
Be sure that it based on ToggleButton instead of ModernButton. In your case you can be interested in some other properties, such an image, title etc.
  • Then create a .xaml file to apply styles such as
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:controls="http://firstfloorsoftware.com/ModernUI"
                    xmlns:converter="clr-namespace:YourNamespace.Converters"
                    xmlns:local="clr-namespace:YourNamespace.CustomControls"
                    xmlns:sys="clr-namespace:System;assembly=mscorlib">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/Converters.xaml" />
        <ResourceDictionary>
            <converter:ResizebleEllipseStrokeThicknessConverter x:Key="StrokeThicknessConverter" />
            <converter:ResizebleModernButtonIconConverter x:Key="IconSizeConverter" />
            <converter:StringNullOrEmptyToVisibilityConverter x:Key="StringToVisibility" />
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>

    <Style TargetType="local:ResizebleModernButton">
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="Foreground" Value="{DynamicResource ModernButtonText}" />
        <Setter Property="Padding" Value="0" />
        <Setter Property="Radius" Value="{DynamicResource defaultButtonRadius}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:ResizebleModernButton">
                    <Grid x:Name="grid"
                          Margin="{TemplateBinding Padding}"
                          Background="Transparent">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>

                        <Grid Width="{TemplateBinding Radius}"
                              Height="{TemplateBinding Radius}"
                              MinWidth="18"
                              MinHeight="18">
                            <Ellipse x:Name="ellipse"
                                     VerticalAlignment="Stretch"
                                     Stroke="{DynamicResource ModernButtonBorder}"
                                     StrokeThickness="{Binding Path=Radius,
                                                               RelativeSource={RelativeSource AncestorType=Button},
                                                               Converter={StaticResource ResourceKey=StrokeThicknessConverter}}" />
                            <Path x:Name="icon"
                                  Width="{Binding Path=Radius,
                                                  RelativeSource={RelativeSource AncestorType=Button},
                                                  Converter={StaticResource ResourceKey=IconSizeConverter}}"
                                  Height="{Binding Path=Radius,
                                                   RelativeSource={RelativeSource AncestorType=Button},
                                                   Converter={StaticResource ResourceKey=IconSizeConverter}}"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"
                                  Data="{TemplateBinding IconData}"
                                  Fill="{TemplateBinding Foreground}"
                                  Stretch="Uniform" />
                        </Grid>
                        <TextBlock Grid.Row="1"
                                   HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                                   VerticalAlignment="{TemplateBinding VerticalAlignment}"
                                   DataContext="{TemplateBinding Content}"
                                   Foreground="{TemplateBinding Foreground}"
                                   Text="{Binding}"
                                   TextTrimming="CharacterEllipsis"
                                   Visibility="{Binding Converter={StaticResource ResourceKey=StringToVisibility}}" />
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Foreground" Value="{DynamicResource ModernButtonTextHover}" />
                            <Setter TargetName="ellipse" Property="Stroke" Value="{DynamicResource ModernButtonBorderHover}" />
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="Foreground" Value="{DynamicResource ModernButtonTextPressed}" />
                            <Setter TargetName="ellipse" Property="Stroke" Value="{DynamicResource ModernButtonBorderPressed}" />
                            <Setter TargetName="ellipse" Property="Fill" Value="{DynamicResource ModernButtonIconBackgroundPressed}" />
                            <Setter TargetName="icon" Property="Fill" Value="{DynamicResource ModernButtonIconForegroundPressed}" />
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource ModernButtonTextDisabled}" />
                            <Setter TargetName="ellipse" Property="Stroke" Value="{DynamicResource ModernButtonBorderDisabled}" />
                        </Trigger>
                        <Trigger Property="IsFocused" Value="true">
                            <Setter TargetName="ellipse" Property="Stroke" Value="{DynamicResource Accent}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>
You must use correct xmlns:converter and xmlns:local namespaces. The best approach is to take a button style from a FirstFloor source code as an example and update it. The most significant job, as I expect, is going to be in the the <ControlTemplate.Triggers> part where you should add trigger for a IsChecked state (and may be others).
  • In your App.xaml use
<ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" />
                <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.Dark.xaml" />

                <ResourceDictionary Source="/YourFolder/YourButton.xaml" />
</ResourceDictionary.MergedDictionaries>
where the /YourFolder/YourButton.xaml is a path to your ToggleButton.


Hope it will help you.
Nov 10, 2013 at 3:54 PM
Tried without success.

In your case, where is exactly converters?
The ResizeableModernButton does not exist in the namespace. in my case, xmlns:local="clr-namespace:RemoteConfigurator.Classes"
an excerpt of the class
namespace RemoteConfigurator.Classes
{
    public class ResizebleModernButton : ModernButton
    {
Thanks.

poborin wrote:
Hi everytimer,

I've end up with no ToggleButton in my current UI design, so I don't have a cooked solution, but it's a quite a straight forward task. Let me show you an example:
  • Create a .cs file with DependecyProperties, in my case it was a:
public class ResizebleModernButton : ModernButton
    {
        public static readonly DependencyProperty RadiusProperty =
            DependencyProperty.Register("Radius", typeof(double), typeof(ResizebleModernButton));

        public double Radius
        {
            get { return (double)GetValue(RadiusProperty); }
            set { SetValue(RadiusProperty, value); }
        }

        static ResizebleModernButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ResizebleModernButton), new FrameworkPropertyMetadata(typeof(ToggleTile)));
        }
    }
Be sure that it based on ToggleButton instead of ModernButton. In your case you can be interested in some other properties, such an image, title etc.
  • Then create a .xaml file to apply styles such as
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:controls="http://firstfloorsoftware.com/ModernUI"
                    xmlns:converter="clr-namespace:YourNamespace.Converters"
                    xmlns:local="clr-namespace:YourNamespace.CustomControls"
                    xmlns:sys="clr-namespace:System;assembly=mscorlib">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/Converters.xaml" />
        <ResourceDictionary>
            <converter:ResizebleEllipseStrokeThicknessConverter x:Key="StrokeThicknessConverter" />
            <converter:ResizebleModernButtonIconConverter x:Key="IconSizeConverter" />
            <converter:StringNullOrEmptyToVisibilityConverter x:Key="StringToVisibility" />
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>

    <Style TargetType="local:ResizebleModernButton">
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="Foreground" Value="{DynamicResource ModernButtonText}" />
        <Setter Property="Padding" Value="0" />
        <Setter Property="Radius" Value="{DynamicResource defaultButtonRadius}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:ResizebleModernButton">
                    <Grid x:Name="grid"
                          Margin="{TemplateBinding Padding}"
                          Background="Transparent">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>

                        <Grid Width="{TemplateBinding Radius}"
                              Height="{TemplateBinding Radius}"
                              MinWidth="18"
                              MinHeight="18">
                            <Ellipse x:Name="ellipse"
                                     VerticalAlignment="Stretch"
                                     Stroke="{DynamicResource ModernButtonBorder}"
                                     StrokeThickness="{Binding Path=Radius,
                                                               RelativeSource={RelativeSource AncestorType=Button},
                                                               Converter={StaticResource ResourceKey=StrokeThicknessConverter}}" />
                            <Path x:Name="icon"
                                  Width="{Binding Path=Radius,
                                                  RelativeSource={RelativeSource AncestorType=Button},
                                                  Converter={StaticResource ResourceKey=IconSizeConverter}}"
                                  Height="{Binding Path=Radius,
                                                   RelativeSource={RelativeSource AncestorType=Button},
                                                   Converter={StaticResource ResourceKey=IconSizeConverter}}"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"
                                  Data="{TemplateBinding IconData}"
                                  Fill="{TemplateBinding Foreground}"
                                  Stretch="Uniform" />
                        </Grid>
                        <TextBlock Grid.Row="1"
                                   HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                                   VerticalAlignment="{TemplateBinding VerticalAlignment}"
                                   DataContext="{TemplateBinding Content}"
                                   Foreground="{TemplateBinding Foreground}"
                                   Text="{Binding}"
                                   TextTrimming="CharacterEllipsis"
                                   Visibility="{Binding Converter={StaticResource ResourceKey=StringToVisibility}}" />
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Foreground" Value="{DynamicResource ModernButtonTextHover}" />
                            <Setter TargetName="ellipse" Property="Stroke" Value="{DynamicResource ModernButtonBorderHover}" />
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="Foreground" Value="{DynamicResource ModernButtonTextPressed}" />
                            <Setter TargetName="ellipse" Property="Stroke" Value="{DynamicResource ModernButtonBorderPressed}" />
                            <Setter TargetName="ellipse" Property="Fill" Value="{DynamicResource ModernButtonIconBackgroundPressed}" />
                            <Setter TargetName="icon" Property="Fill" Value="{DynamicResource ModernButtonIconForegroundPressed}" />
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource ModernButtonTextDisabled}" />
                            <Setter TargetName="ellipse" Property="Stroke" Value="{DynamicResource ModernButtonBorderDisabled}" />
                        </Trigger>
                        <Trigger Property="IsFocused" Value="true">
                            <Setter TargetName="ellipse" Property="Stroke" Value="{DynamicResource Accent}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>
You must use correct xmlns:converter and xmlns:local namespaces. The best approach is to take a button style from a FirstFloor source code as an example and update it. The most significant job, as I expect, is going to be in the the <ControlTemplate.Triggers> part where you should add trigger for a IsChecked state (and may be others).
  • In your App.xaml use
<ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" />
                <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.Dark.xaml" />

                <ResourceDictionary Source="/YourFolder/YourButton.xaml" />
</ResourceDictionary.MergedDictionaries>
where the /YourFolder/YourButton.xaml is a path to your ToggleButton.


Hope it will help you.
Jan 25, 2015 at 7:56 AM
Edited Jan 25, 2015 at 8:10 AM
Quite simple ToggleButton template with dynamic resource links to ModernUI template properties
    <Style TargetType="ToggleButton">
        <Setter Property="Background" Value="{DynamicResource ButtonBackground}"></Setter>
        <Setter Property="BorderBrush" Value="{DynamicResource ButtonBorder}"></Setter>
        <Setter Property="Foreground" Value="{DynamicResource ButtonText}"></Setter>


        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Border BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}">                        
                        <ContentPresenter Margin="1"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Button.Background" Value="{DynamicResource ButtonBackgroundHover}"></Setter>
                <Setter Property="Button.BorderBrush" Value="{DynamicResource ButtonBorderHover}"></Setter>
            </Trigger>
            <Trigger Property="IsPressed" Value="True">
                <Setter Property="Button.Background" Value="{DynamicResource ButtonBackgroundPressed}"></Setter>
                <Setter Property="Button.BorderBrush" Value="{DynamicResource ButtonBorderPressed}"></Setter>
            </Trigger>
            <Trigger Property="IsChecked" Value="true">
                <Setter Property="Button.Background" Value="{DynamicResource ButtonBackgroundPressed}"></Setter>
                <Setter Property="Button.BorderBrush" Value="{DynamicResource ButtonBorderPressed}"></Setter>
            </Trigger>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Button.Foreground" Value="{DynamicResource ButtonTextDisabled}"></Setter>
                <Setter Property="Button.BorderBrush" Value="{DynamicResource ModernButtonBorderDisabled}"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
Usage with Path as the content (binding is needed to change foreground for disabled state):
                <ToggleButton Name="butSelect" Width="25" Height="25"  Margin="1" ToolTip="Selection mode" IsEnabled="False">
                    <Path  Stretch="Uniform" Fill="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ToggleButton}}, Path=Foreground}" Data="F1 M 29,18L 52.25,41.1667L 43.0865,42.6585L 50.817,56.6949L 43.827,60.4115L 36,46.25L 29,53.25L 29,18 Z "/>
                </ToggleButton>