Showing posts with label Triggers. Show all posts
Showing posts with label Triggers. Show all posts

Sunday, March 20, 2011

Open source WPFInspector

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 !!!

http://wpfinspector.codeplex.com

Sunday, July 4, 2010

Common Code Base 2 Styles and Templates

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.

  • Don’t write any inline styles.Use resource dictionaries.
  • Merge the resource dictionaries at the application level only.

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

Sunday, July 12, 2009

Different styles for alternate rows in ListBox

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.

Monday, May 11, 2009

Writing custom TriggerAction using Interaction to enhance MVVM

The Blend team has introduced a new concept called Interactions for both WPF and Silverlight.According to my understanding it is a method to interact with the xaml elements without writing code behind.Expression Blend is developed using the new architectural concept MVVM and I think they mainly introduced it to enhance MVVM.

There are 2 methods to implement this interaction.One is Behaviors and other is Triggers.Behaviors will be covered in a separate post.This post is related with Triggers, Actions and creation of  a custom Action called FollowMouse.

I have already wrote a post about Microsoft.Expression.Interactivity.dll which tells about creating a custom trigger named RoutedEventTrigger which fires on the associated RoutedEvent.In that post, the intention was to invoke a command upon attached events like Mouse.MouseDown,Mouse.MouseMove,Contacts.ContactDown etc…That is too, very much useful to achieve a perfect MVVM architecture.

In the perfect MVVM world there should be no code behind for xaml files.But when we implement in the real world ,sometimes we will be forced to write code behind to implement some special cases such as MessageBox.Show.Using the Microsoft.Expression.Interactivity.dll we can write actions which display the messagebox.

More links about the behaviors and interactions are below

http://electricbeach.org/?p=147
http://blog.kirupa.com/?p=341

What are these new Interactions

As I told earlier this is a method to interact without writing code behind.The code will be encapsulated in the action classes.See the example below which shows  a MessageBox using only xaml upon a MouseDown.

<Grid Background="Red">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<myactions:ShowMessageBoxAction MessageBoxText="Mouse down" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Grid>


Hope the above code is clear.It tells to show a MessageBox upon MouseDown in the Grid.We know that it is not possible or don’t have default support in xaml to show the message itself.Then where is the C# code to show the message.The answer is simple.It is in the ShowMessageBoxAction class.That class has a MessageBoxText property which is displayed on invoking that action.


To implement interaction it is using attached properties.Interaction.Triggers is an attached property of type TriggerCollection.We can add as many triggers we want.The condition is that all those triggers should be derived from TriggerBase.Here I have used built in EventTrigger and a custom action ShowMessageBoxAction.


Developing our own custom Trigger Action : FollowMouseAction


Writing a custom trigger action is very simple.There should be a reference to the Microsoft.Expression.Interactivity.dll in our project.That dll is from Expression Blend 3 so it should be blend installed in your system to refer.Path is <Install drive>:\Program Files\Microsoft Expression\Blend 3 Preview\Libraries\WPF.Or you can download from any blogs.


The action class ,we need to derive from the base class named Microsoft.Expression.Interactivity.TargetedTriggerAction<T> this has a generic parameter which is the type of the target.


Here we are going to implement a FollowMouseAction.The purpose of this is to create an action which follows mouse and updates it’s position according to that.For that we have to associate trigger to a Canvas.Canvas is the simple panel in which children can be easily placed by specifying Left and Top.So at the time of inheriting class we have to specify the Canvas as it’s action type.


One more thing we need is which child of canvas is following the mouse.So we have to add one more property called Element which is of type FrameworkElement.On action invocation we will be setting the Canvas.Left and Canvas.Top properties of Element according to the mouse position.




public class FollowMouseAction : Microsoft.Expression.Interactivity.TargetedTriggerAction<Canvas>
{
public FrameworkElement Element
{
get { return (FrameworkElement)GetValue(ElementProperty); }
set { SetValue(ElementProperty, value); }
}

// Using a DependencyProperty as the backing store for element. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ElementProperty =
DependencyProperty.Register("Element", typeof(FrameworkElement), typeof(FollowMouseAction), new UIPropertyMetadata(null));

protected override void Invoke(object parameter)
{
Point pt = Mouse.GetPosition(this.Target);
if (Element != null)
{
Element.SetValue(Canvas.LeftProperty, pt.X);
Element.SetValue(Canvas.TopProperty, pt.Y);
}
}
}

Using the FollowMouseAction in xaml.



<Grid>
<Canvas Width="300" Height="300" Background="Red">
<Ellipse Width="50"
Height="50"
Fill="Green"
x:Name="ele">
</Ellipse>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<myactions:FollowMouseAction Element="{Binding ElementName=ele}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>
</Grid>


The above code updates mouse position when we click on the mouse.How can we make it movable accoring mouse ?Easy just change the event name to “MouseMove”.See below if you are still not clear.



<Grid>
<Canvas Width="300" Height="300" Background="Red">
<Ellipse Width="50"
Height="50"
Fill="Green"
x:Name="ele">
</Ellipse>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseMove">
<myactions:FollowMouseAction Element="{Binding ElementName=ele}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>
</Grid>



NB: Please don’t confuse these Triggers and Actions with the standard triggers and actions available in WPF.They are entirely different where the Triggers mentioned here comes from the namespace Microsoft.Expression.Interactivity and the standard WPF Triggers comes from System.Windows



The above is applicable to Silverlight too.The only change you have to to do is change the reference to the interactivity dll located at <install drive>:\Program Files\Microsoft Expression\Blend 3 Preview\Libraries\Silverlight.If you need more and more details please see this great article from my colleague Laurent Bugnion 


Sample can be downloaded from here.