Friday, January 4, 2013

WPF using PART while creating Control Template


A simple progress bar example


One of the most useful features of WPF is the ability to completely redesign the look of a control such a button, progress bar or slider bar relatively easily through the use of control templates.

With complex controls (such as the progress bar) you can keep the functionality of the original control and save having to re-write the base logic. This is done by specifying that elements in your design are the same as part of the original control. The link is created through simply naming your elements by set names usually prefixed with PART_.

In the example below we have a ControlTemplate for a ProgressBar. In order for it to keep it’s function as a progress bar the I have named the elements “PART_Track” and “PART_Indicator” to link to the two parts of original functionality. In the case of a progress bar without this when the value property is set on the progresses bar it would not be reflected in the redesigned control.



 


 
XAML Code


<Window x:Class="PARTExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ControlTemplate x:Key="myProgressbar" TargetType="{x:Type ProgressBar}">
            <Grid x:Name="PART_Track">
                <Border CornerRadius="10" Background="Bisque"></Border>              
                <Grid Name="PART_Indicator" HorizontalAlignment="Left">
                    <Border CornerRadius="10" Background="BurlyWood"></Border>
                </Grid>
            </Grid>
        </ControlTemplate>
    </Window.Resources>
    <Grid>
        <ProgressBar Template="{StaticResource myProgressbar}"  Height="27" HorizontalAlignment="Left" Margin="64,93,0,0" Name="progressBar1" VerticalAlignment="Top" Width="381"/>
        <Button Content="Start" Height="20" HorizontalAlignment="Left" Margin="213,190,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
    </Grid>
</Window>





Code Behind 

using System;
using System.Windows;
using System.Threading.Tasks;
using System.Threading;

namespace PARTExample
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            progressBar1.Minimum = 0;
            progressBar1.Maximum = 1000;                      
        }

        private void ProcessProgress()
        {
           short i  = 0 ;
           while (i++ < 1000)
           {
               progressBar1.Dispatcher.Invoke(new Action(()=>progressBar1.Value=i));
               Thread.Sleep(5);
           }
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            Task.Factory.StartNew(() => ProcessProgress());
        }
    }
}



No comments:

Post a Comment