Showing posts with label Control Template. Show all posts
Showing posts with label Control Template. Show all posts

Monday, December 26, 2011

WPF - Toggle Button


Toggle button is similar to checkbox control that holds its state when it clicked.  When Toggle button clicked first time it will set IsChecked property to true and on click again it will set IsChecked property to false. Toggle button also fires Checked event when IsChecked property set to true and UnChecked event when set to false. Toggle button is available in System.Windows.Controls.Premitives namespace.

Toggle Button also implements IsThreeState property. If IsThreeState property is enabled, the first click sets IsChecked property to true, the second click sets it to null and the third click sets it to false. 

Let’s have a look on below example.

<Window.Resources>
    <Style TargetType="{x:Type ToggleButton}"
           x:Key="toggleButtonStyle">
        <Setter Property="FontWeight" Value="Bold" />
        <Style.Triggers>
            <Trigger Property="IsChecked" Value="True">
                <Setter Property="Content" Value="IsChecked='True'" />
                <Setter Property="Foreground" Value="Green" />
            </Trigger>
            <Trigger Property="IsChecked" Value="False">
                <Setter Property="Content" Value="IsChecked='False'" />
                <Setter Property="Foreground" Value="Red" />
            </Trigger>
            <Trigger Property="IsChecked" Value="{x:Null}">
                <Setter Property="Content" Value="IsChecked='Null'" />
                <Setter Property="Foreground" Value="Blue" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <ToggleButton IsChecked="True"
                    IsThreeState="True"
                    Height="30" Width="150"
                    Style="{StaticResource toggleButtonStyle}">
    </ToggleButton>
</Grid>

IsChecked property set to true when application starts, and text color of Toggle Button appears as ‘green’.



On toggle button click, IsChecked property set to null and text color changes to ‘blue’.


Again click on toggle button, IsChecked property set to false and text color changes to  ‘red’.




See Also – 


Wednesday, October 12, 2011

How to get default control template of WPF controls?


All WPF developer might aware about Control Templates in WPF. We can create custom control templates and apply those to controls. By default every WPF control has its own default control template. In this post I will explain how to get default control template from control.

Let’s have a look on below code which writes default template of control in console or output window.

<Window x:Class="WPFTestApplication.DefaultControlTemplate"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Default Control Template" Height="200" Width="200">
    <Grid>
        <ListBox Name="listBox1" />
    </Grid>
</Window>

void DefaultControlTemplate_Loaded(object sender, RoutedEventArgs e)
{
    StringBuilder stringBuilder = new StringBuilder();

    XmlWriterSettings xmlSettings = new XmlWriterSettings();
    xmlSettings.Indent = true;

    using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, xmlSettings))
    {
        XamlWriter.Save(listBox1.Template, xmlWriter);
    }

    Console.WriteLine(stringBuilder.ToString());
}

Output

<?xml version="1.0" encoding="utf-16"?>
<ControlTemplate TargetType="ListBox" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="1,1,1,1" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="Bd" SnapsToDevicePixels="True">
    <ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
      <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
    </ScrollViewer>
  </Border>
  <ControlTemplate.Triggers>
    <Trigger Property="UIElement.IsEnabled">
      <Setter Property="Panel.Background" TargetName="Bd">
        <Setter.Value>
          <DynamicResource ResourceKey="{x:Static SystemColors.ControlBrushKey}" />
        </Setter.Value>
      </Setter>
      <Trigger.Value>
        <s:Boolean>False</s:Boolean>
      </Trigger.Value>
    </Trigger>
    <Trigger Property="ItemsControl.IsGrouping">
      <Setter Property="ScrollViewer.CanContentScroll">
        <Setter.Value>
          <s:Boolean>False</s:Boolean>
        </Setter.Value>
      </Setter>
      <Trigger.Value>
        <s:Boolean>True</s:Boolean>
      </Trigger.Value>
    </Trigger>
  </ControlTemplate.Triggers>
</ControlTemplate>

Above example writes the default template of listbox control in console/output window using XML writer. You can use this default template and modify the way you want in your application. You can also save this template in xml file too. Let’s have a look on below code.

void DefaultControlTemplate_Loaded(object sender, RoutedEventArgs e)
{
    XmlWriterSettings xmlSettings = new XmlWriterSettings();
    xmlSettings.Indent = true;

    using (XmlWriter xmlWriter =
     XmlWriter.Create(@"D:\Temp\DefaultTemplate.xml", xmlSettings))
    {
        System.Windows.Markup.XamlWriter.Save(listBox1.Template, xmlWriter);
    }
}

Hope you liked this tip to get default control template programmatically. Please feel free to write feedback/comments in comments section below.

See also –




Friday, September 23, 2011

Template Binding in WPF


Template Binding is similar to normal data binding except it optimize only for Template. The properties are binding used in template binding are coming from the control whose template you are changing. This parent control is called as templated parent. Template binding is subset of normal data binding. Template binding doesn't allow value conversion. Template binding allows the control template to pick up the value specified on an element. Using template binding we can create flexible control template instead of fixed or rigid. Specifying Template binding is very simple, need to specify TemplateBinding markup extension and followed by the property name which you wanted to bind with. Let's have a look on below example.

<Window.Resources>
<ControlTemplate x:Key="ButtonTemplate" TargetType="Button">
    <Grid Margin="{TemplateBinding Margin}"
          Height="{TemplateBinding Height}"
          Width="{TemplateBinding Width}">
        <Ellipse x:Name="ButtonEllipse"
                    Height="100" Width="100"
                    Fill="LightBlue">
        </Ellipse>
        <ContentPresenter Content="{TemplateBinding Content}"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center" />
    </Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<Button Content="Click Me!"
        Margin="10" Width="150"
        Height="150"
        Template="{StaticResource ButtonTemplate}"/>
</Grid>













As demonstrated template binding in above example, grid’s Margin, Height and Width properties are bound using template binding. It means specified Height, Width and Margin property on button will automatically applies to button template. If don’t specified those properties it will automatically take default value of property. Content presenter’s content property is also bound with Button’s content property using Template Binding.


See also - 

Wednesday, September 14, 2011

Control Template in WPF


Control template is core component of WPF. Controls in WPF are made from so many components and elements. This is called as visual representation of control. Control Templates are used to replace Visual Tree of an element.

Each control has its own default control template with basic appearance. Control has dependency property called Template. Setting this property can replace appearance of control. Control Template can be specified inside style or in resource file or in resource element of window/user control. Control template can be set to particular type like Button, Listbox, Menu etc.

Control Template also allows you to specify behavior using Trigger or Visual State Manager. In below example I have used trigger to change behavior of control. You can visit my separate post on the Visual State Manager in WPF for more information.


<Window.Resources>
<ControlTemplate x:Key="ButtonTemplate" TargetType="Button">
    <Grid>
        <Ellipse x:Name="ButtonEllipse" Height="100" Width="100" >
            <Ellipse.Fill>
                <LinearGradientBrush StartPoint="0,0.2"
                                     EndPoint="0.2,1.4">
                    <GradientStop Offset="0" Color="Cyan"/>
                    <GradientStop Offset="1" Color="Blue"/>
                </LinearGradientBrush>
            </Ellipse.Fill>
        </Ellipse>
        <ContentPresenter Content="{TemplateBinding Content}"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center" />
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter TargetName="ButtonEllipse" Property="Fill" >
                <Setter.Value>
                    <LinearGradientBrush StartPoint="0,0.2"
                                         EndPoint="0.2,1.4">
                        <GradientStop Offset="0" Color="Pink"/>
                        <GradientStop Offset="1" Color="Red"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="RenderTransform">
                <Setter.Value>
                    <ScaleTransform ScaleX="0.8" ScaleY="0.8"
                                    CenterX="0" CenterY="0"  />
                </Setter.Value>
            </Setter>
            <Setter Property="RenderTransformOrigin"
                    Value="0.5,0.5" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<StackPanel>
<Button Content="Click Me!"
        Template="{StaticResource ButtonTemplate}"
        Width="150" Margin="5" />
<Button Content="Click Me!" Height="40"
        Width="150" Margin="5" />
</StackPanel>
















As per above example, First image demonstrates two buttons first one is with Template and second one is without Template. In second image first button background changed when mouse is hover over the button.

As per XAML code snippet, ButtonTemplate is defined inside window’s resources. Inside ButtonTemplate, Ellipse element is added inside grid and set its background with linear gradient. Also added Content Presenter which is used to display content of button. In our case we set ‘Click Me!’ content to button which will automatically added to Content Presenter because it has template binding with content element of parent control.

Triggers are also added to control template to change behavior of control on certain event. In above code we defined property trigger on IsMouseOver property and IsPressed property. So when mouse hover over the button it will change color specified in linear gradient of setter element and when button is pressed it will scale transform button to 0.8. So the whole control size will reduce when button is pressed.


See also -