Showing posts with label XAML. Show all posts
Showing posts with label XAML. Show all posts

Thursday, July 31, 2014

MVVm views without C# code behind file

The MVVm is a great technique for separating the concerns. If we take ASP.Net MVC we can see it is built for using model view controller model. So by default wont allow us to write code behind for the views (We can write inside the cshtml though). But WPF as the technology was not built to use WPF to there is no in-built way to avoid the code behind of views. 

If the development team is so technology focused, it doesn't matter as they won't break the rules of MVVm even if there is code behind file. But since companies are offshoring to get cheap labor, enforcing quality is little tricky. As always cheap things comes with less quality. Most of the time people's priority is to get things done in quick way ie by writing everything in code behind instead of going through viewmodel. 

The challenge here is how to bring quality with these less skilled labor? One of the way to enforce viewmodel  usage is to delete the code behind of views which is nothing but the user controls.

If we just remove the usercontrol.xaml.cs, it will fail as the Initialize method is missing. So how to overcome is?

Add the Initialize method in the view itself. Yes we can write C# code in XAML. So the view user control will look as follows.

<UserControl x:Class="Joymons.MVVmDemo.Views.MainView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <x:Code>
        <![CDATA[ public MainView() { InitializeComponent(); }]]>
    </x:Code>
            <TabControl ItemsSource="{Binding ChildVMs}" SelectedIndex="0">
                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Header}" />
                    </DataTemplate>
                </TabControl.ItemTemplate>
            </TabControl>
</UserControl>

I too started using VS 2013. That is why a black background in the code :)

Friday, February 24, 2012

MVVm - Embed C# code in XAML like ASP.Net MVC

It is long time since I posted something in this blog. I know this is my most famous blog with average 200hits/day but I was mainly concentrating into the other aspects of .Net such as CLR, WCF, ASP.Net, Windows Phone 7 etc than this XAML based display technology. There are 2 main inspirations for this post.

First one is a comment which I got on my post related to opacitymask and its usage in WPF. The specialty of that is, it came from a MSFT guy. I don't know how others are thinking, but for me its little important. Even I am not sure whether that MSFT is just something else or that person just added MSFT :-)

The second reason is "This is my 100th post on WPF technology and I want that to be something special and useful". I was in search for such a topic and just found today, while I was working with ASP.Net MVC 3 application.

The problem
Anyway I am not wasting time on introduction.Lets come to the topic. As everybody knows MVVm is the widely accepted pattern for the XAML based technologies such as WPF and Silverlight. The main reason I could see is the data binding support. By design the pattern is not expecting anything in the code behind and everything related to business should reside in the viewmodel. Its all fine.We can have data binding and commands to separate the view from vm. But what can I do with the dialogs? Since they are UI is that desirable to call showdialog from viewmodel or should I write code behind for views and pass the dialog result to vm through event aggregator or any other messaging mechanism? Mainly this comes into picture when we need to browse for a file or show a messagebox in MVVm based application.

There are something called behaviors and triggers in an expression blend dll named System.windows.interactivity which we can leverage to accomplish the same. But are there any better way? Yes another way is to call the ShowDialog from the vm itself and process it. This is what I was following till I came to play more with ASP.Net MVC pattern.

What is special with ASP.Net MVC
MVC is another UI pattern to separate the UI from its business. When Microsoft implemented a framework to write asp.net applications using the same, people started calling it as ASP.Net MVC. Actually there is no relation between ASP.Net and MVC .Anybody can implement MVC in their application without MSFT framework.

The specialty I noticed in MVC framework is, there is no option to write code behind. In the RAZOR view we cannot even find a code behind file. I wondered how people are accomplishing their tasks without writing the code behind for views. Theoretically we can say "don't write code behind" .But I have never seen a big enterprise application in MVVm without code behind for at least one view.Coming back to ASP.Net MVC, the RAZOR don't give us option to write code behind but provides support to embed code inside the view itself.
Yes the idea flashed in my head and I could recollect one of my old post which explains embedding code    inside the xaml file .That is the way to handle the dialog boxes better.

Solution : Embed C# or VB.Net code in xaml view
This doesn't mean we should move the code behind file into the view. This helps to write the dialog handling code in the view itself. Below is one example of such an implementation.


    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <TextBox x:Name="txtFileName"
                 Text="{Binding FilePath,UpdateSourceTrigger=PropertyChanged}" />
        <Button Grid.Column="1" Content="Browse" Click="Clicked" />
        <x:Code>
            <![CDATA[
void Clicked(object sender, RoutedEventArgs e)
{
            Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
            ofd.DefaultExt = ".exe";
            ofd.Filter = "Executables (.exe)|*.exe"; // Filter files by extension

            // Show open file dialog box
            Nullable<bool> result = ofd.ShowDialog();
            // Process open file dialog box results
            if (result.HasValue && result.Value)
            {
                // Set value to textbox which will update the property of VM
                txtFileName.Text= ofd.FileName;
            }
}
]]>
        </x:Code>
        <Button Content="Start"
                Grid.Column="2"
                Command="{Binding StartCommand}" />
    </Grid>

Pros and Cons
One thing to notice is that we need to give name to the controls which other developers may use to write code behind.Next thing how to show a message dialog box in this way .For that we need to keep a property in the vm and bind to a hidden textbox . Wire the TextChanged event of textbox to an event handler in the view as how the above C# code is written .
Main development challenge will be how to write code without intellisense .Yes you don't get intellisense when writing code inside xaml file.One way to overcome is to write the code in normal file and copy paste.

Sunday, August 8, 2010

Common Code Base 3 handling controls

Another issue you are going to face is the namespace and assembly differences of classes in WPF and Silverlight.Especially you will find when dealing with controls.ie the classes will be there with same methods and properties.But in different namespaces or assemblies .That prevent us from having common code base.

Lets just consider the case of TreeView in System.Windows.Controls namespace which is present in both WPF and Silverlight.In WPF it is in the assembly PresentationFramework.dll but in Silverlight its System.Windows.Controls.dll. Ideally the schema mapping should do the correct mapping and we should be able to use the xaml. But unfortunately it is not mapped to the schema.Means if we use common xaml file for tree view it will show a compilation error in Silverlight.

The tag 'TreeView' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'.

Does this indicate we should stop common code? Not at all.We have one solution which uses inheritance as a hack.I didn’t even think, inheritance will have such a usage.Solution is as follows.

  1. Create your own class for TreeView by inheriting the framework TreeView.Have this linked to WPF too.
  2. Use your treeview throughout the application.
Public Class CCBTreeView
Inherits System.Windows.Controls.TreeView
End Class


CCBTreeView would be in your controls project which refers PresentationFramework.dll and System.Windows.Controls.dll in WPF and Silverlight respectively. While using, use as follows.


<UserControl x:Class="TestCompatibility.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CCBControls="clr-namespace:CCB.Controls;assembly=CCB.Controls">
<CCBControls:CCBTreeView ItemsSource="{Binding Persons}" />
</UserControl>


This applies to so many controls such as HierarchicalDataTemplate,TabControl etc which differs in namespace or assembly.Refer the sample uploaded here if you still have confusion.Also let me know if anybody have better solution to this problem.

Previous posts on Common Code Base

----------------------------------------------

Common Code Base 1 Introduction

Common Code Base 2 Styles and Templates

Saturday, August 7, 2010

Debugging WPF and Silverlight DataBinding

Good article about debugging data binding in WPF and silverlight.

http://blogs.msdn.com/b/wpfsldesigner/archive/2010/06/30/debugging-data-bindings-in-a-wpf-or-silverlight-application.aspx

In short we can debug databinding in 2 ways

  1. Looking at the output/immediate window.
  2. Using converters.
  3. Putting break points in get and set regions of properties

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

Wednesday, September 23, 2009

Auto formatting XAML code

Here is one way to format our XAML code in a neat way.In VisualStudio open the Options dialog. Tools->Options.

Goto TextEditor->XAML->Formatting->Spacing and set the options as per the below image.

Set it as XAML coding practice and do a smooth code review...

Tuesday, May 19, 2009

WatermarkTextBox by inheriting TextBox

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

  1. Subclass TextBox and create a new class called WatermarkTextBox.
  2. Add a new DP called Watermark which is of type object.
  3. In the generic.xaml write the default style.
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));
}

And its style in generic.xaml contains almost same elements as of my last post.But here I have used TemplateBinding to set Watermark into the TextBlock.

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

Tuesday, March 31, 2009

DataBinding to App.Settings values

.Net 2.0 introduced this feature which helps to store and retrieve application specific settings very easily.You can easily create Settings through the visual editor.If we want to access them in code we can just use the Properties.Settings.Default object directly.The Default object will have all the properties which we had created at design time.
Showing ConnectionString entry in Messagebox
MessageBox.Show(Properties.Settings.Default.ConnectionString);


It is very easy.Lets learn how this can be binded in to a WPF TextBox.

First make a namespace reference to the Properties namespace.If your application name is WpfApplication1 it is xmlns:props=”WpfApplication1.Properties”.

Then in the Binding set source as the Default property available in the class Settings.Since it is static you have to use the x:Static binding extension.

Finally the path is ConnectionString which is the settings entry name.

Putting it altogether.


<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication1.Window1"
x:Name="Window"
xmlns:props="clr-namespace:WpfApplication1.Properties">
<Grid x:Name="LayoutRoot">
<TextBox  HorizontalAlignment="Left"  VerticalAlignment="Top"
Text="{Binding Source={x:Static props:Settings.Default},Path=ConnectionString}">
</TextBox>
</Grid>
</Window>


So enjoy WPF data binding to Properties.Settings.Default.

Tuesday, March 24, 2009

Writing custom Pixel shader effects.

What are Pixel shaders

Pixel shaders are programs which operates on each pixel before displaying in the screen.Pixel shaders are not part of Silverlight or WPF.They are more related to the Graphics cards and DirectX.They use a language called HLSL (High Level Shader Language) for programming.It has more similarities to C than C#.More details on HLSL is available here.

Coding Pixel Shader : Negative.Fx

Coding in HLSL refers some registers and all.Here is the code for a Negative Effect.

sampler2D implicitInput : register(s0);

float4 PS(float2 uv : TEXCOORD) : COLOR
{
float4 color = tex2D(implicitInput, uv);

float4 result;

result.r=1-color.r;
result.g=1-color.g;
result.b=1-color.b;
result.a=color.a;

return result;
}



We are getting the color value of pixel in float4 located at uv and returning a color (result)which is inverse of the given color.

Compiling a Pixel Shader

The extension of the Pixel shader files will be .FX.We need to have DirectX SDK installed in our machine in order to compile HLSL (*.fx) source code to *.ps bytecode that can be loaded using Silverlight’s PixelShader class. Fxc.exe is the HLSL compiler used to compile *.fx HLSL shader files. The following command shows how to compile Negative.fx:


Current folder : [Install drive]:\Program Files\Microsoft DirectX SDK (November 2008)\Utilities\bin\x86 (Change the month according to the version you have)


fxc.exe /T ps_2_0 /E PS /FoNegative.ps Negative.fx

/T ps_2_0 :Compiles against the ps_2_0 target pixel shader level that WPF currently supports
/E PS : Marks the function 'PS' as the entry point
/FoNegative.ps Negative.fx : Negative.fx as input and output to Negative.ps. Note that there is no space between /Fo and Greyscale.ps

The command above can be used as pre-build event of a Visual Studio project to automate the build process.


Creating Custom Shader Effect class


Add the output .ps file as Resource in the project.Once we add the .ps file we can start writing the .Net interface class for that.It is derived from the ShaderEffect class and we need to add some things there.See the below code.



public class Negative : ShaderEffect
{
private static PixelShader _pixelShader = new PixelShader()
{
UriSource = new
Uri("pack://application:,,,/WpfCustomEffect;component/Negative.ps",
UriKind.RelativeOrAbsolute)
};

public static readonly DependencyProperty InputProperty =
ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(Negative), 0);
public Brush Input
{
get { return (Brush)GetValue(InputProperty); }
set { SetValue(InputProperty, value); }
}

public Negative()
{
this.PixelShader = _pixelShader;
UpdateShaderValue(InputProperty);
}
}



PixelShader is the protected property in ShaderEffect class and that should be initialized with a new instance which refers to our .ps file.Then we creates a dependency property which is of type Brush and associates to the shader.Creating dependency property is a bit different here.We need to use ShaderEffect.RegisterPixelShaderSamplerProperty method in order to create the DP.


Using Custom Pixel Shader


We can use the new Effect from either XAML or C# code behind.



<Image x:Name="img"
Source="Autumn.jpg">
<Image.Effect>
<effect:Negative />
</Image.Effect>
</Image>
<Button Grid.Row="1"
Click="Button_Click"
Content="Click to change">
<Button.Effect>
<effect:Negative />
</Button.Effect>
</Button>




private void Button_Click(object sender, RoutedEventArgs e)
{
if (img.Effect == null)
{
img.Effect = new Negative();
}
else
{
img.Effect = null;
}
}



Sample can be downloaded from here.

Wednesday, February 25, 2009

Limitations of XamlWriter.Save method

XamlWriter.Save method is very much useful if we need to preserve the state of an application.But when I used this method extensively, I came to know some limitations.Here is the list.

  1. From Microsoft http://msdn.microsoft.com/en-us/library/ms754193.aspx
  2. We can't save Style of a control which contains VisualStateManger nodes ie we will loose vsm support if we save using XamlWriter.Save method.

Will be extending whenever I find more.

Friday, February 13, 2009

Readymade XAML Styles and Templates

Designer free development in WPF
A great look and feel matters everywhere in WPF.If you had selected WPF for your project developement ,it's UI design should be stunning and excellent.
But what to do if there are no designers in your company ? Or the designers in your company don't have enough knowledge in XAML and Blend.Some time the project doesn't have enough budget to employ a designer.
Here comes the importance of ready made XAML Style packs and templates.Style packs or Xaml templates library means a collection of global Styles and templates for all standard controls which can be inserted in to your resource dictionary.Thus all your controls in that application will be in the same theme.
I just saw a site which provides these type of xaml templates.I think there will be some more companies or sites which provide ready made xaml assets.So the below list will grew as I come across new style pack providers.

Tuesday, February 10, 2009

Creating WPF Watermarked TextBox using Expression Blend

Here are the steps to create a watermarked TextBox in WPF using Expression Blend as I promised in my last post.

  1. Create a new WPF application in Expression Blend
    • Click on File menu
    • Then click on New Project.Select WPF Application
    • Name as "WaterMarkedTextBox"
  2. Create a TextBox control and set it's Text="".
  3. Now create a Button control .Button is to test the focus lost event of TextBox.
  4. Set the Width and Height of These controls in order to get displayed properly.
  5. Now edit the template of TextBox.
    • Right click on the TextBox shown in Objects and Timeline panel.
    • Select "Edit Control Parts (Template)"
    • Then select "Edit a copy"
      BlendWTB1
    • Select location and press "OK".
  6. Now put the ScrollViewer named "PART_ContentHost" into a grid
    • Right click on the ScrollViewer in Objects and TimeLine.

    • Select "Group into" then "Grid".
  7. Now add a TextBlock named "watermark" into the newly created Grid
    • Double click on the newly created Grid to select it.
    • Add a TextBlock.
    • Set its Text as "Enter here".
    • Set Visibility="Hidden".
    • Set Opacity=".35" ie 35%
  8. Now add a Multi Trigger which fires on the condition IsFocused="False" and Text=""It sets the visibility of TextBlock "watermark" to Visible.
    • Click on the "+ Property" Button in the interaction pan to create trigger.
    • Change the Property Name to "IsFocused" and Value to "False" in the first record of "Activated when" area.Don't change the target-element.
    • Now click on the "+" button available in the same row of "Activated when" to add one more condition.
    • In the new condition set property as Text and Value as "" ie empty string.Better leave value as it is.By default it will take the empty string.
    • Now select the watermark TextBlock.Set it's visibility.
      BlendWTB3
  9. Now the Template editing is over.Save and run the application.

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.

Monday, February 9, 2009

WPF Watermark TextBox using XAML Style

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.


Friday, January 23, 2009

Innerglow in WPF using Expression blend and xaml

WPF doesn't have support for Inner glow by default.This is an important feature in rich user interface designs.So to implement Innerglow in our application we have to workaroud the issue.Here you can find one good workaround by a Microsoft employee.
http://blogs.msdn.com/msmossyblog/archive/2008/09/15/how-to-make-innerglows-with-expression-blend.aspx

Remember the BitmapEffects in WPF are very costly

Saturday, December 13, 2008

Creating custom wpf markup extension to show class fields

Here is one link which describes what is markup extension and available markup extensions.
Markup extensions are very much useful to obtain a clean project.Things won't get mixed with each other.Xaml itself contains the lines which have the functionality.

Consider the scenario where we need to display all properties of given class in a listbox.We normally write C# or VB code to get PropertyInfo objects and return the same.This code normally resides in presentation files itself.

Here comes the need for markup extension.We can write our own extension by inheriting from the MarkUpExtension class.

Steps to Create a custom markup extension

  1. Create a class which derives from MarkupExtension.The naming convention is that the class name should ends with 'Extension' .Eg:TypeDescriptorExtension
  2. If we need to accept a default parameter with extension write a constructor
  3. Add other properties as well.
  4. Override ProvideValue Method and return the appropriate value after processing.

Eg: Creating custom markup extension to list Properties and methods of a Class

The PropertyDescriptorExtension class is derived from Markupextension and it accepts an object Type as default parameter.So the constructor is written with a parameter of type 'Type'.

public class TypeDescriptorExtension:MarkupExtension
{
public TypeDescriptorExtension( Type type):this()
{
Type = type;
}
}

The other properties are IncludeProperties and InCludeMethods which are boolean to indicate whether the out put list should include Properties and Methods respectively.IncludeProperties is true by default.

Now override the ProvideValue method.Get the properties and methods collection based on the properties using Reflection and return as well.

public override object ProvideValue(IServiceProvider serviceProvider)
{
if (Type == null)
{
throw new InvalidOperationException("The Class must be specified.");
}
List<string> items = new List<string>();

if (IncludeProperties)
{
foreach (PropertyInfo item in Type.GetProperties())
{
items.Add(item.ToString());
}
}
if (IncludeMethods)
{
foreach (MethodInfo info in Type.GetMethods())
{
items.Add(info.ToString());
}
}
return items;
}

Using the TypeDescriptorExtension
Normal, which displays only properties

 <ListBox ItemsSource="{Binding Source={local:TypeDescriptor {x:Type Button}}}" />
Displays methods only
 <ListBox ItemsSource="{Binding Source={local:TypeDescriptor {x:Type Button},IncludeMethods=True,IncludeProperties=False}}" />

Sample is available here.