Another Snoop like debugging tool for WPF.But this is useful to debug and inspect DataContext,Resources,Triggers & Styles.
I don’t want to compare this with Snoop.Check it out yourself !!!
Abt me :Now a mad rider on the WPF road
Another Snoop like debugging tool for WPF.But this is useful to debug and inspect DataContext,Resources,Triggers & Styles.
I don’t want to compare this with Snoop.Check it out yourself !!!
As everybody knows Silverlight doesn’t support the Triggers which are most common in WPF.That means we cannot use WPF styles as it is.So obviously we need to create new styles even for Silverlight 4 which are same in behavior but using different xaml.Below are the best practices which we can follow to tackle the styles and templates in Common Code Base scenario.
This will solve the issue with basic styles.Think of a scenario where you are loading the styles dynamically.In WPF you can handle this using DynamicResource binding extension.But the sad thing is Silverlight doesn’t support DynamicResource. So what is the solution.
The solution which we applied was very easy.Use StaticResource in the XAML files and load the styles through code in the App.xaml.vb file.Yes it worked in WPF too.
Download sample from here to see the styles and templates in action in CCB.(See the foreground of Button.Its coming through Style)
Previous posts on Common Code Base
----------------------------------
Common Code Base 1 Introduction
Simple but important feature which really help us in real-time applications.Giving different look and feel or colors to alternate rows helps users to differentiate two consecutive rows in a ListBox or ListView.Basically controls which are derived from ItemsControl.
Below xaml code shows how alternate colors are applied into a ListBox
Xaml code to create ListBox with 6 items
<ListBox AlternationCount="2">
<ListBoxItem Content="Item1" />
<ListBoxItem Content="Item2" />
<ListBoxItem Content="Item3" />
<ListBoxItem Content="Item4" />
<ListBoxItem Content="Item5" />
<ListBoxItem Content="Item6" />
</ListBox>
Xaml code of the Style which has the alternate style support.Note the change is in the ItemContainerStyle.Here Style is applied to ListBoxItem
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex"
Value="0">
<Setter Property="Background"
Value="LightBlue"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex"
Value="1">
<Setter Property="Background"
Value="LightGreen"></Setter>
</Trigger>
</Style.Triggers>
</Style>
When we run it shows as follows
Description
Here the ItemsControl has got most of the implementation part.It has some members which control the behavior of alternate style.The attached property ItemsControl.AlternationIndex tells the index and according to that we can change color or anything through style.
The Alternation count specifies the frequency.Below code uses 3 as ItemsControl.AlternationCount.See the difference.
Creating ListBox
<ListBox AlternationCount="3">
<ListBoxItem Content="Item1" />
<ListBoxItem Content="Item2" />
<ListBoxItem Content="Item3" />
<ListBoxItem Content="Item4" />
<ListBoxItem Content="Item5" />
<ListBoxItem Content="Item6" />
</ListBox>
Style supports AlternationCount=3
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex"
Value="0">
<Setter Property="Background"
Value="LightBlue"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex"
Value="1">
<Setter Property="Background"
Value="LightGreen"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex"
Value="2">
<Setter Property="Background"
Value="LightYellow"></Setter>
</Trigger>
</Style.Triggers>
</Style>
I don't think a sample is needed.
I am very happy to see that my previous post “WPF Watermark TextBox using XAML Style” helped a lot of peoples to solve their issues and currently that is the most popular post in my blog.That post describes about creating a WPF watermark textbox by changing it’s style.All the things are done in xaml and there is no property to set the water mark text.
There was a requirement from one of the readers for such a property.ie a Watermark property which decides the watermark text.So rewriting the sample with that property.
Here I just derived a new class called WatemarkTextBox from standard TextBox added a new dependency property called Watermark and defined default style for that control in generic.xaml.The steps are as follows
public class WatermarkTextBox : TextBox
{
static WatermarkTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(WatermarkTextBox),
new FrameworkPropertyMetadata(typeof(WatermarkTextBox)));
}
public object Watermark
{
get { return (object)GetValue(WatermarkProperty); }
set { SetValue(WatermarkProperty, value); }
}
// Using a DependencyProperty as the backing store for Watermark. This enables animation, styling, binding, etc...
public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register(
"Watermark",
typeof(object),
typeof(WatermarkTextBox),
new UIPropertyMetadata(null));
}
<Style TargetType="{x:Type local:WatermarkTextBox}">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
<Setter Property="BorderBrush"
Value="Blue" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Padding"
Value="1" />
<Setter Property="AllowDrop"
Value="true" />
<Setter Property="FocusVisualStyle"
Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:WatermarkTextBox}">
<Grid>
<Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd"
SnapsToDevicePixels="true"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
RenderFocused="{TemplateBinding IsKeyboardFocusWithin}"
RenderMouseOver="{TemplateBinding IsMouseOver}">
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Microsoft_Windows_Themes:ListBoxChrome>
<TextBlock x:Name="textBlock"
Opacity="0.345"
Text="{TemplateBinding Watermark}"
TextWrapping="Wrap"
Visibility="Hidden" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused"
Value="False" />
<Condition Property="Text"
Value="" />
</MultiTrigger.Conditions>
<Setter Property="Visibility"
TargetName="textBlock"
Value="Visible" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Download sample from here.
Here are the steps to create a watermarked TextBox in WPF using Expression Blend as I promised in my last post.
N.B : It is recommended to see the generated XAML to ensure the output.The XAML may differ if you had clicked in wrong places.
What is watermarked TextBox
Watermarked TextBox is a special type of text input control which displays a message or image when it is empty.Usually the message will be "Enter the text" and sometimes it may be description about that data field.
When we click on the TextBox ie getting focus the watermark text ("Enter the text") will disappear and it will become an ordinary TextBox.
Developing Watermark TextBox
The tasks of developer are hiding the watermark on getting focus and showing again on lost focus, if the user doesn't entered value in that.ie if the TextBox is empty watermark should come again.
In earlier days this itself was a control which is inherited from normal TextBox.But with the help of Templating and Trigger support in WPF we could achieve it very easily without inheriting.Just by Stying and Templating an ordinary TextBox.
Structure of Watermark TextBox Style
The style can be based on the style of TextBox itself.This reduces our effort in implementing normal TextBox behaviors.We are just going to concentrate on Template.
The normal TextBox template contains a ScrollViewer to hold the data.We are just going to put a TextBlock over that which is going to hold the Watermark text("Enter the Text").By default the visibility of this new TextBlock will be hidden.
Inside ControlTemplate
<Grid>
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<TextBlock x:Name="textBlock"
Opacity="0.345"
Text="Enter Text Here"
TextWrapping="Wrap"
Visibility="Hidden" />
</Grid>
Now we write Trigger to show this TextBlock on demand.There are two conditions which shows this watermark.They are "IsFocused=False" and Length of the Text=0.So we write a MultiTrigger with 2 conditions in it.One is for LostFocus and other is for Text.Length respectively.
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused"
Value="False" />
<Condition Property="Text"
Value="" />
</MultiTrigger.Conditions>
<Setter Property="Visibility"
TargetName="textBlock"
Value="Visible" />
</MultiTrigger>
</ControlTemplate.Triggers>
Now whenever the TextBox comes in a state where the IsFocused=False and Text="" the Watermark TextBlock will get displayed.You can replace the watermark TextBlock by any image or what ever you want..
Complete Style
<Style x:Key="WaterMarkTextBoxStyle"
BasedOn="{StaticResource {x:Type TextBox}}"
TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<TextBlock x:Name="textBlock"
Opacity="0.345"
Text="Enter Text Here"
TextWrapping="Wrap"
Visibility="Hidden" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused"
Value="False" />
<Condition Property="Text"
Value="" />
</MultiTrigger.Conditions>
<Setter Property="Visibility"
TargetName="textBlock"
Value="Visible" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This can be done by a graphics designer alone.That means using Expression Blend.Will be posting steps later.