Saturday 4 May 2013

WPF Markup Extension Sample Code Snippets

In last post, we have seen an brief overview of Markup Extension and different types of Markup Extensions.

I thought it would be useful to create a sample that uses all Markup Extensions. You can download the sample: Download Code – Sample containing all Markup Extensions

Also I am posting code snippets for all Markup Extension for quick reference.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFMarkupExtension
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private string simpleText = "Text set using Binding Markup Extension";
public string SimpleText
{
get { return simpleText; }
set { simpleText = value; }
}

private string firstName = "Text set using";
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}

private string lastName = "MultiBinding Markup Extension";
public string LastName
{
get { return lastName; }
set { lastName = value; }
}

//private string bindingValue1 = "first binding";
//public string BindingValue1
//{
// get
// {
// throw new ApplicationException();
// return bindingValue1;
// }
//}

private string bindingValue2 = "Second binding returned value successfully";
public string BindingValue2
{
get { return bindingValue2; }
set { bindingValue2 = value; }
}

public static string StaticField = "Text set using Static Markup Extension";

public MainWindow()
{
InitializeComponent();
}
}
}

 

<Window x:Class="WPFMarkupExtension.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFMarkupExtension"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="600" Width="600">
<Window.Resources>
<SolidColorBrush x:Key="LightBlueColor" Color="LightBlue"></SolidColorBrush>
<local:MyConverter x:Key="myConverter"></local:MyConverter>

<!--Usage of x:Array Marukup Extension-->
<x:ArrayExtension x:Key="fruits" Type="sys:String">
<sys:String>Apple</sys:String>
<sys:String>Orage</sys:String>
<sys:String>Mango</sys:String>
<sys:String>Banana</sys:String>
</x:ArrayExtension>

<!--Usage of x:Type Maukup Extension-->
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="5"></Setter>
<Setter Property="Padding" Value="5"></Setter>
</Style>

<!--Usage of TemplateBinding Markup Extension-->
<ControlTemplate x:Key="EllipseButton" TargetType="{x:Type Button}">
<Grid>
<!--TemplateBinding is used to set property of control in ControlTemplate to property of
parent control to which this template is applied.-->
<!--Instead of specifying hard code value for Fill property, we inherit property from
parent control. This adds flexibility to template.-->
<Ellipse Fill="{TemplateBinding Background}"></Ellipse>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
</Grid>
</ControlTemplate>
</Window.Resources>
<StackPanel>

<GroupBox Header="XAML Defined">
<StackPanel>
<!--Usage of x:Null Markup Extension-->
<!--Style defined for TextBlock in Window.Resources section applies to all TextBlock.
We want this particular TextBlock not to use that style. So we set Style to Null-->
<TextBlock Style="{x:Null}" Text="Null Markup extension usage"></TextBlock>

<!--Usage of x:Static Markup Extension-->
<!--local refers to namespace of current project which is imported in Window element at top
MainWindow refers directly to Class (and not instance of Class)
StaticField is static property in MainWindow class-->
<TextBlock Text="{x:Static Member=local:MainWindow.StaticField}"></TextBlock>
</StackPanel>
</GroupBox>

<GroupBox Header="WPF Specific">
<!--Usage of RelativeResource Markup Extension-->
<!--DataContext for StackPanel is set to current window (means code behind).
Hence all controls in this StackPanel will inherit this DataContext as source for binding.-->
<StackPanel DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">
<TextBlock Background="LightBlue"
Text="Background property set using direct string vlaue"></TextBlock>

<!--Usage of StaticResource Markup Extension (Attribute Syntax) -->
<TextBlock Background="{StaticResource ResourceKey=LightBlueColor}"
Text="Background property set using StaticResource Markup Extension - Attribute Syntax"></TextBlock>

<!--Usage of StaticResource Markup Extension (Property Element Syntax) -->
<TextBlock Text="Background property set using StaticResource Markup Extension - Property Element Syntax">
<TextBlock.Background>
<StaticResource ResourceKey="LightBlueColor"></StaticResource>
</TextBlock.Background>
</TextBlock>

<!--Usage of DynamicResource Markup Extension (Attribute Syntax) -->
<TextBlock Background="{DynamicResource ResourceKey=LightBlueColor}"
Text="Background property set using DynamicResource Markup Extension"></TextBlock>

<!--Usage of Binding Markup Extension (Attribute Syntax) -->
<TextBlock Text="{Binding SimpleText}"></TextBlock>

<!--Usage of Binding Markup Extension (Property Element Syntax) -->
<TextBlock>
<TextBlock.Text>
<Binding Path="SimpleText"></Binding>
</TextBlock.Text>
</TextBlock>

<!--Usage of MultiBinding Markup Extension-->
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<!--StringFormat is can be used for simple string concat/manipulation.
For complex requirements ValueConverter can be used as commented below-->
<!--<MultiBinding Converter="{StaticResource ResourceKey=myConverter}"
StringFormat="{}{0} {1}">-->
<Binding Path="FirstName"></Binding>
<Binding Path="LastName"></Binding>
</MultiBinding>
</TextBlock.Text>
</TextBlock>

<!--Usage of StaticResource Markup Extension-->
<ListBox ItemsSource="{StaticResource ResourceKey=fruits}"></ListBox>

<!--Usage of PriorityBinding Markup Extension-->
<TextBlock HorizontalAlignment="Left">
<TextBlock.Text>
<!--PriorityBinding can be used for sharing same data template with multiple
controls or for showing progress in async operations.-->
<PriorityBinding>
<!-- // First Binding is not present or binding throws exception
or does not return some value then Second Binding is used -->
<Binding Path="BindingValue1"></Binding>
<Binding Path="BindingValue2"></Binding>
</PriorityBinding>
</TextBlock.Text>
</TextBlock>

<!--Usage of TemplateBinding Markup Extension-->
<!--See EllipseButton ControlTemplate-->
<Button Width="150" Height="75" Content="TemplateBinding usage" HorizontalAlignment="Left"
Background="LightBlue" Template="{StaticResource ResourceKey=EllipseButton}">
</Button>
</StackPanel>
</GroupBox>
</StackPanel>
</Window>

No comments:

Post a Comment