Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

Dynamic Button Control (C# code or XAML code)

2.63/5 (6 votes)
8 Jun 2009CPOL3 min read 64.2K   3.4K  
Dynamic Button Control (C# code or XAML code)
Article_src

Introduction

This is a simple button control which is created by XAML and C# code. These techniques are used by two languages, either XAML or C# . In both cases, the functionality is the same but the declaration is different. The following functionalities are used to create a control.

1. ResourceDictionary

ResourceDictionary class is typically an implicit collection element that is the object element value of several Resources properties.

2. Style

A style is most commonly declared as a resource inside the Resources section. Because styles are resources, they obey the same scoping rules that apply to all resources, so where you declare a style affects where it can be applied. If, for instance, you declare the style in the root element of your application definition XAML file, the style can be used anywhere in your application. If you are creating a navigation application and declare the style in one of the application's XAML files, the style can be used only in that XAML file.

3. ControlTemplate

The ControlTemplate allows you to specify the visual structure of a control. The control author can define the default ControlTemplate and the application author can override the ControlTemplate to reconstruct the visual structure of the control.

4. Triggers

WPF defines properties that correspond to end-user actions, such as the IsMouseOver property that is set to true when the user hovers the cursor over a UIElement or the corresponding IsMouseOver property of a ContentElement. Representing end-user actions in property values, along with the Trigger element, allows WPF styles to change property values based on those end-user actions, all from within markup.

5. GradientBrush

A LinearGradientBrush paints an area with a linear gradient. A linear gradient defines a gradient along a line. The line's end points are defined by the StartPoint and EndPoint properties of the linear gradient. A LinearGradientBrush brush paints its GradientStops along this line. The default linear gradient is diagonal. In the default, the StartPoint of a linear gradient is (0,0), the upper-left corner of the area being painted, and its EndPoint is (1,1), the lower-right corner of the area being painted. The colors in the resulting gradient are interpolated along the diagonal path.

6. FrameworkElementFactory

Supports the creation of templates.

C# Source Code

C#
this.Content = "C#Code";

//-----------------------------------GlassBackgroundFill--------------------------------

LinearGradientBrush gradient_GlassBackgroundFill = new LinearGradientBrush();
gradient_GlassBackgroundFill.StartPoint = new Point(0, 0);
gradient_GlassBackgroundFill.EndPoint = new Point(0, 1);

GradientStop color_BackgroundFill = new GradientStop();
color_BackgroundFill.Offset = 0;
color_BackgroundFill.Color = (Color)ColorConverter.ConvertFromString("#ff4b58");

GradientStop color2_BackgroundFill = new GradientStop();
color2_BackgroundFill.Offset = 1;
color2_BackgroundFill.Color = (Color)ColorConverter.ConvertFromString("#a91e28");

gradient_GlassBackgroundFill.GradientStops.Add(color_BackgroundFill);
gradient_GlassBackgroundFill.GradientStops.Add(color2_BackgroundFill);

//------------------------------------HoverGlassBackgroundFill-------------------------

RadialGradientBrush gradient_HoverGlassBackgroundFill = new RadialGradientBrush();
gradient_HoverGlassBackgroundFill.Center = new Point(0.5, 0.5);

GradientStop color_HoverGlassBackgroundFill = new GradientStop();
color_HoverGlassBackgroundFill.Offset = 0;
color_HoverGlassBackgroundFill.Color = 
	(Color)ColorConverter.ConvertFromString("#a91e28");

GradientStop color2_HoverGlassBackgroundFill = new GradientStop();
color2_HoverGlassBackgroundFill.Offset = 1;
color2_HoverGlassBackgroundFill.Color = 
	(Color)ColorConverter.ConvertFromString("#ff4b58");

gradient_HoverGlassBackgroundFill.GradientStops.Add(color_HoverGlassBackgroundFill);
gradient_HoverGlassBackgroundFill.GradientStops.Add(color2_HoverGlassBackgroundFill);

//---------------------------------HighlightFill---------------------------------------

LinearGradientBrush highlightFill = new LinearGradientBrush();
highlightFill.StartPoint = new Point(0, 0);
highlightFill.EndPoint = new Point(0, 1);

GradientStop color_highlightFill = new GradientStop();
color_highlightFill.Offset = 0;
color_highlightFill.Color = (Color)ColorConverter.ConvertFromString("#FFFFFFFF");

GradientStop color2_highlightFill = new GradientStop();
color2_highlightFill.Offset = 1;
color2_highlightFill.Color = (Color)ColorConverter.ConvertFromString("#00000000");

highlightFill.GradientStops.Add(color_highlightFill);
highlightFill.GradientStops.Add(color2_highlightFill);

//---------------------------------BorderStroke---------------------------------------
LinearGradientBrush borderStroke = new LinearGradientBrush();
borderStroke.StartPoint = new Point(0, 0);
borderStroke.EndPoint = new Point(0, 1);

GradientStop color_borderStroke = new GradientStop();
color_borderStroke.Offset = 0;
color_borderStroke.Color = (Color)ColorConverter.ConvertFromString("#c7c7c7");

GradientStop color2_borderStroke = new GradientStop();
color2_borderStroke.Offset = 1;
color2_borderStroke.Color = (Color)ColorConverter.ConvertFromString("#b0b0b0");

borderStroke.GradientStops.Add(color_borderStroke);
borderStroke.GradientStops.Add(color2_borderStroke);

//------------------------------------------------------------------------------------

ControlTemplate template = new ControlTemplate(typeof(Button));

FrameworkElementFactory grid = new FrameworkElementFactory(typeof(Grid));
grid.SetValue(Grid.RenderTransformOriginProperty, new Point(0.5, 0.5));

//------------------------------------------------------------------------------------

FrameworkElementFactory ele_BorderStock = new FrameworkElementFactory(typeof(Border));
ele_BorderStock.Name = "Outline";
ele_BorderStock.SetValue(Border.CornerRadiusProperty, new CornerRadius(9.0));
ele_BorderStock.SetValue(Border.BackgroundProperty, Brushes.Red);
ele_BorderStock.SetValue(Border.BorderBrushProperty, borderStroke);
ele_BorderStock.SetValue(Border.BorderThicknessProperty, new Thickness(1));

FrameworkElementFactory ele_GlassBackground = 
		new FrameworkElementFactory(typeof(Rectangle));
ele_GlassBackground.Name = "GlassBackground";
ele_GlassBackground.SetValue(Rectangle.MarginProperty, new Thickness(1, 1, 2, 2));
ele_GlassBackground.SetValue(Rectangle.RadiusXProperty, 9.0);
ele_GlassBackground.SetValue(Rectangle.RadiusYProperty, 9.0);
ele_GlassBackground.SetValue(Rectangle.FillProperty, gradient_GlassBackgroundFill);

FrameworkElementFactory ele_Highlight = new FrameworkElementFactory(typeof(Rectangle));
ele_Highlight.SetValue(Rectangle.MarginProperty, new Thickness(1, 1, 2, 2));
ele_Highlight.SetValue(Rectangle.RadiusXProperty, 9.0);
ele_Highlight.SetValue(Rectangle.RadiusYProperty, 9.0);
ele_Highlight.SetValue(Rectangle.OpacityProperty, 1.0);
ele_Highlight.SetValue(Rectangle.FillProperty, highlightFill);

FrameworkElementFactory ContentPresenterAll =
	new FrameworkElementFactory(typeof(ContentPresenter));
ContentPresenterAll.SetValue
	(ContentPresenter.VerticalAlignmentProperty, VerticalAlignment.Center);
ContentPresenterAll.SetValue
	(ContentPresenter.HorizontalAlignmentProperty, HorizontalAlignment.Center);

grid.AppendChild(ele_BorderStock);
grid.AppendChild(ele_GlassBackground);
grid.AppendChild(ele_Highlight);
grid.AppendChild(ContentPresenterAll);

//---------------------------ControlTemplate.Triggers.IsMouseOver------------------------

Trigger tg_IsMouseOver = new Trigger();
tg_IsMouseOver.Property = IsMouseOverProperty;
tg_IsMouseOver.Value = true;

Setter str_IsMouseOver = new Setter();
str_IsMouseOver.TargetName = "GlassBackground";
str_IsMouseOver.Property = Rectangle.FillProperty;
str_IsMouseOver.Value = gradient_HoverGlassBackgroundFill;
tg_IsMouseOver.Setters.Add(str_IsMouseOver);

template.Triggers.Add(tg_IsMouseOver);

//------------------------ControlTemplate.Triggers.IsPressed-----------------------------

Trigger tg_IsPressed = new Trigger();
tg_IsPressed.Property = Button.IsPressedProperty;
tg_IsPressed.Value = true;

Setter str_IsPressed = new Setter();
str_IsPressed.TargetName = "GlassBackground";
str_IsPressed.Property = Rectangle.FillProperty;
str_IsPressed.Value = Brushes.Red;
tg_IsPressed.Setters.Add(str_IsPressed);

template.Triggers.Add(tg_IsPressed);
//---------------------------------------------------------------------------------------

template.VisualTree = grid;

Style newStyle = new Style();
newStyle.TargetType = typeof(Button);

Setter str_margin = new Setter(Button.MarginProperty, new Thickness(1.0));
Setter str_snapsToDevicePixes = new Setter(Button.SnapsToDevicePixelsProperty, true);
Setter str_OverridesDefaultStyle = 
	new Setter(Button.OverridesDefaultStyleProperty, true);
Setter str_minHeight = new Setter(Button.MinHeightProperty, 16.0);
Setter str_minWidth = new Setter(Button.MinWidthProperty, 16.0);
Setter str_fontFamiy = new Setter(Button.FontFamilyProperty, new FontFamily("Verdana"));
FontSizeConverter myFontSizeConverter = new FontSizeConverter();
Setter str_fontSize = new Setter
    (Button.FontSizeProperty, (Double)myFontSizeConverter.ConvertFromString("11px"));
Setter str_foreground = new Setter(Button.ForegroundProperty, Brushes.White);
Setter str_ModifiedTemplate = new Setter(TemplateProperty, template);

newStyle.Setters.Add(str_margin);
newStyle.Setters.Add(str_snapsToDevicePixes);
newStyle.Setters.Add(str_OverridesDefaultStyle);
newStyle.Setters.Add(str_minHeight);
newStyle.Setters.Add(str_minWidth);
newStyle.Setters.Add(str_fontFamiy);
newStyle.Setters.Add(str_fontSize);
newStyle.Setters.Add(str_foreground);
newStyle.Setters.Add(str_ModifiedTemplate);

this.Style = newStyle;

XAML Source Code

XML
<Style x:Key="GlassButton" TargetType="{x:Type Button}">
   <Setter Property="Margin" Value="1" />
   <Setter Property="SnapsToDevicePixels" Value="true"> </Setter>
   <Setter Property="OverridesDefaultStyle" Value="true"> </Setter>
   <Setter Property="MinHeight" Value="16"> </Setter>
   <Setter Property="MinWidth" Value="16"> </Setter>
   <Setter Property="FontFamily" Value="Verdana"> </Setter>
   <Setter Property="FontSize" Value="11px" />
   <Setter Property="Foreground" Value="White" />
   <Setter Property="Template">
     <Setter.Value>
       <ControlTemplate TargetType="Button" >
           <Grid x:Name="Content" RenderTransformOrigin="0.5,0.5">
           <Border Name="Outline" CornerRadius="9"
           Background="{StaticResource ButtonPushedFill}"
              BorderBrush="{StaticResource BorderStroke}"
              BorderThickness="1" />
             <!-- Background -->
           <Rectangle x:Name="GlassBackground"
           Margin="1,1,2,2" RadiusX="9" RadiusY="9"
            Fill="{StaticResource GlassBackgroundFill}">
           </Rectangle>
           <Rectangle x:Name="Highlight" Margin="1,1,2,2" RadiusX="9"
            RadiusY="9" Opacity="1" Fill="{StaticResource HighlightFill}">
              </Rectangle>
           <!-- This aligns the text in the center of the button -->
           <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />
           </Grid>

           <!-- Triggers -->
           <ControlTemplate.Triggers>
              <Trigger Property="IsMouseOver" Value="true">
                 <Setter TargetName="GlassBackground"
       Property="Fill" Value="{StaticResource HoverGlassBackgroundFill}" />
              </Trigger>
              <Trigger Property="IsPressed" Value="true">
                 <Setter TargetName="GlassBackground"
       Property="Fill" Value="{StaticResource ButtonPushedFill}" />
              </Trigger>

           </ControlTemplate.Triggers>

          </ControlTemplate>
         </Setter.Value>
         </Setter>
         </Style>

About the Author

I started my IT career in 2003 with C++ and VC++, I gained good experience in the IT industry. Finally I moved to .NET Technologies and I am involved in many .NET projects. I have good experience in packaging and deployment of .NET projects. I have worked on Graphics and digital imaging process, and developed an algorithm for high speed printing in graphics mode, this was one great success in that project. I have developed custom controls in C#. I also have good knowledge of latest technologies like WPF and WCF, good learning skills and interest to work on advanced technologies. Currently I am working for Wipro Technologies. My hobbies include reading books, swimming, and listening to music.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)