We saw one example of attached dependency property here. In that example we convert the string to title case using attached dependency property. Now lets extend this concept further. We already have one example of string convert where we convert string to base64, title case, lower case and upper case here. Lets make a attached dependency property to do the same thing. First thing we do is to change the class name to StringBehavior and changed the attached dependency property name from Title to Conversion. Here is our class.
{
public static readonly DependencyProperty ConversionProperty =
DependencyProperty.RegisterAttached("Conversion",
typeof(string), typeof(StringBehavior),
new PropertyMetadata(new PropertyChangedCallback(ToConversionCallBack)));
public static void SetConversion(UIElement element, string value)
{
element.SetValue(ConversionProperty, value);
}
public static string GetConversion(UIElement element)
{
return (string)element.GetValue(ConversionProperty);
}
static void ToConversionCallBack(DependencyObject obj,
DependencyPropertyChangedEventArgs args)
{
string newValue = (string)args.NewValue;
TextBlock text = obj as TextBlock;
if (newValue.ToUpper() == "BASE64")
{
byte[] txtByte = Encoding.Default.GetBytes(text.Text);
string outputString = System.Convert.ToBase64String(txtByte);
text.SetValue(TextBlock.TextProperty, outputString);
}
else if (newValue.ToUpper() == "TITLE")
{
TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
text.SetValue(TextBlock.TextProperty, ti.ToTitleCase(text.Text));
}
else if (newValue.ToUpper() == "UPPER")
{
text.SetValue(TextBlock.TextProperty, text.Text.ToUpper());
}
else if (newValue.ToUpper() == "LOWER")
{
text.SetValue(TextBlock.TextProperty, text.Text.ToLower());
}
}
}
Now we make a list view to use the different parameter of attach dependency property in different columns. Here is a usage of our dependency property.
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Margin="2" local:StringBehavior.Conversion="Title" Text="{Binding Path=.}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
We do the same thing with all columns of the list view. Here is complete XAML code of our program.
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfAttachedProperty"
Title="Attached Property" Height="350" Width="525">
<Grid>
<ListView ItemsSource="{Binding}">
<ListView.View>
<GridView>
<GridViewColumn Header="Title" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Margin="2" local:StringBehavior.Conversion="Title" Text="{Binding Path=.}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Upper" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Margin="2" local:StringBehavior.Conversion="Upper" Text="{Binding Path=.}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Lower" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Margin="2" local:StringBehavior.Conversion="Lower" Text="{Binding Path=.}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Base64" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Margin="2" local:StringBehavior.Conversion="Base64" Text="{Binding Path=.}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Here is complete C# code of the program.
using System.Globalization;
using System.Text;
using System.Windows;
using System.Windows.Controls;
namespace WpfAttachedProperty
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ObservableCollection<string> states = new ObservableCollection<string>();
public MainWindow()
{
InitializeComponent();
states.Add("maryland");
states.Add("virginia");
states.Add("washington");
states.Add("california");
DataContext = states;
}
}
public class StringBehavior
{
public static readonly DependencyProperty ConversionProperty =
DependencyProperty.RegisterAttached("Conversion",
typeof(string), typeof(StringBehavior),
new PropertyMetadata(new PropertyChangedCallback(ToConversionCallBack)));
public static void SetConversion(UIElement element, string value)
{
element.SetValue(ConversionProperty, value);
}
public static string GetConversion(UIElement element)
{
return (string)element.GetValue(ConversionProperty);
}
static void ToConversionCallBack(DependencyObject obj,
DependencyPropertyChangedEventArgs args)
{
string newValue = (string)args.NewValue;
TextBlock text = obj as TextBlock;
if (newValue.ToUpper() == "BASE64")
{
byte[] txtByte = Encoding.Default.GetBytes(text.Text);
string outputString = System.Convert.ToBase64String(txtByte);
text.SetValue(TextBlock.TextProperty, outputString);
}
else if (newValue.ToUpper() == "TITLE")
{
TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
text.SetValue(TextBlock.TextProperty, ti.ToTitleCase(text.Text));
}
else if (newValue.ToUpper() == "UPPER")
{
text.SetValue(TextBlock.TextProperty, text.Text.ToUpper());
}
else if (newValue.ToUpper() == "LOWER")
{
text.SetValue(TextBlock.TextProperty, text.Text.ToLower());
}
}
}
}
This is the output of the program.
[…] of string convertor here. We also implemented this in the form of Attached Dependency property here. Now we are going to implement the same thing with markup extension. We are going to use the same […]
By: String Converter Revisited « Zeeshan Amjad's WPF Blog on November 24, 2011
at 12:23 pm