Monday, October 31, 2011

How to pass data as an argument to Thread?


In this post I will explain how to pass parameters to thread’s method. There are multiple ways to achieve this. Let’s have a look on below easiest way to pass arguments to thread’s method.

public static void main()
{
    Thread t = new Thread(DisplayMessage);
    t.Start("Mitesh");
}
public void DisplayMessage(object msg)
{
    Console.WriteLine("Hello " + msg.ToString());
}

Output
Hello Mitesh

In above example, DisplayMessage method takes one argument as an object and display passed arguments. The new thread initialization has reference of DisplayMessage and Thread constructor takes two types of argument one is ThreadStart and another is ParameterizedThreadStart. So this method will treat as ParameterizedThreadStart. The ParameterizedThreadStart will take only one argument and that argument should be passed as an object. The Start method of Thread takes one argument as an object so we can pass only one argument to start method of Thread.

Let’s have a look on another way to pass data as an argument to Thread.

public static void main()
{
    Thread t = new Thread(() => DisplayMessage("Mitesh"));
    t.Start();
}
public void DisplayMessage(object msg)
{
    Console.WriteLine("Hello " + msg.ToString());
}

Or

public static void main()
{
    Thread t = new Thread(delegate() { DisplayMessage("Mitesh"); });
    t.Start();
}
public void DisplayMessage(object msg)
{
    Console.WriteLine("Hello " + msg.ToString());
}
Output
Hello Mitesh

We can also pass arguments using Lambda expression or using anonymous method as shown in above examples.

Hope you liked this tip. Please leave your feedback and comments in comment section below in this post.

See also –


Wednesday, October 12, 2011

How to get default control template of WPF controls?


All WPF developer might aware about Control Templates in WPF. We can create custom control templates and apply those to controls. By default every WPF control has its own default control template. In this post I will explain how to get default control template from control.

Let’s have a look on below code which writes default template of control in console or output window.

<Window x:Class="WPFTestApplication.DefaultControlTemplate"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Default Control Template" Height="200" Width="200">
    <Grid>
        <ListBox Name="listBox1" />
    </Grid>
</Window>

void DefaultControlTemplate_Loaded(object sender, RoutedEventArgs e)
{
    StringBuilder stringBuilder = new StringBuilder();

    XmlWriterSettings xmlSettings = new XmlWriterSettings();
    xmlSettings.Indent = true;

    using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, xmlSettings))
    {
        XamlWriter.Save(listBox1.Template, xmlWriter);
    }

    Console.WriteLine(stringBuilder.ToString());
}

Output

<?xml version="1.0" encoding="utf-16"?>
<ControlTemplate TargetType="ListBox" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="1,1,1,1" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="Bd" SnapsToDevicePixels="True">
    <ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
      <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
    </ScrollViewer>
  </Border>
  <ControlTemplate.Triggers>
    <Trigger Property="UIElement.IsEnabled">
      <Setter Property="Panel.Background" TargetName="Bd">
        <Setter.Value>
          <DynamicResource ResourceKey="{x:Static SystemColors.ControlBrushKey}" />
        </Setter.Value>
      </Setter>
      <Trigger.Value>
        <s:Boolean>False</s:Boolean>
      </Trigger.Value>
    </Trigger>
    <Trigger Property="ItemsControl.IsGrouping">
      <Setter Property="ScrollViewer.CanContentScroll">
        <Setter.Value>
          <s:Boolean>False</s:Boolean>
        </Setter.Value>
      </Setter>
      <Trigger.Value>
        <s:Boolean>True</s:Boolean>
      </Trigger.Value>
    </Trigger>
  </ControlTemplate.Triggers>
</ControlTemplate>

Above example writes the default template of listbox control in console/output window using XML writer. You can use this default template and modify the way you want in your application. You can also save this template in xml file too. Let’s have a look on below code.

void DefaultControlTemplate_Loaded(object sender, RoutedEventArgs e)
{
    XmlWriterSettings xmlSettings = new XmlWriterSettings();
    xmlSettings.Indent = true;

    using (XmlWriter xmlWriter =
     XmlWriter.Create(@"D:\Temp\DefaultTemplate.xml", xmlSettings))
    {
        System.Windows.Markup.XamlWriter.Save(listBox1.Template, xmlWriter);
    }
}

Hope you liked this tip to get default control template programmatically. Please feel free to write feedback/comments in comments section below.

See also –




Tuesday, October 11, 2011

Static vs Dynamic resources in WPF


A resource can be referenced as either static or dynamic resource. This can be done by using either Static resource markup extension or Dynamic resource markup extension. You can go through my post on Markupextension in WPF for more information about markup extension.

  1. The major difference between static and dynamic resources is “static resource will evaluate the resource only once while dynamic resource will be evaluated every time the resource needed”.
  2. Dynamic resource has more performance overhead than static resources because it look up for resources every time it requested or needed.
  3. Static resource is faster but it takes little more time to load page or window than dynamic resource because dynamic resources are loaded when you actually used those.
  4. If resource is defined on the element’s resources and the same element property is using the resource defined inside its resources then static resource not applied because it should appears afterwards. The same thing is valid for dynamic resource. Let’s have a look on below code snippet.
       Below code gives compile time error.
       <Grid Background="{StaticResource lightBlueColor}">
         <Grid.Resources>
            <SolidColorBrush Color="LightBlue" x:Key="lightBlueColor"/>
         </Grid.Resources>
       </Grid>
          The same is valid for dynamic resource
       <Grid Background="{DynamicResource lightBlueColor}">
         <Grid.Resources>
            <SolidColorBrush Color="LightBlue" x:Key="lightBlueColor"/>
         </Grid.Resources>
       </Grid>

Below example gives you clear picture about Static and Dynamic resource markup extension.

XAML
<Window.Resources>
    <SolidColorBrush Color="LightBlue" x:Key="buttonBackground" />
</Window.Resources>
<StackPanel Name="stkPanel">
    <Button Name="Button1" Content="Button1"
            Width="150" Height="40" Margin="5"
            Background="{StaticResource buttonBackground}"/>
    <Button Name="Button2" Content="Button2"
            Width="150" Height="40" Margin="5"
            Background="{DynamicResource buttonBackground}"/>
    <Button Name="Button3" Content="Button3"
            Width="150" Height="40" Margin="5"
            Background="{StaticResource buttonBackground}"/>
</StackPanel>

Code behind
void StaticAndDynamicResources_Loaded(object sender, RoutedEventArgs e)
{
    stkPanel.Resources["buttonBackground"] = Brushes.Yellow;
}

Output















As shown in above example, three buttons are using buttonBackground resource defined in windows.resources element. Button1 and Button3 are using static resource markup extension while button2 is using dynamic resource markup extension. After loading of my window, I have changed color of buttonBackground resource from Lightblue to Yellow in code behind. So when I run my application, Button2 will have yellow background and rest of the buttons will have LightBlue background. The reason behind for not changing background of Button1 and Button3 because both button uses static resource and static resource is loaded only once with application while button2 uses dynamic resource and it changes every time when it accessed. 


Hope you liked this article. Please feel free to write feedback/comments in comment section below.

See also - 

Friday, October 7, 2011

WPF Resources


WPF resource system allows you to keep useful objects around you so you can reuse easily. There are multiple ways to define Resources in WPF. In this post I will explain all the ways where we can define and use resources. Resource element defines a resource dictionary and dictionary requires every item to have key, so we must provide key to every resource declared inside resource dictionary.

Declaring resource inside element’s resources property -

You can declare resources which are going to be used inside your current window those resources can be declared inside Window.Resources element. In fact almost every resource in WPF has resources property so you can set anywhere you want. But the resources are accessible to the element and its child elements. Resources declared at top element (root level element) can be accessible to every element in window. In below example I have declared resources in window.resources element so every elements of window will have access those resources.

<Window x:Class="WpfApplication1.WPFResourcesDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WPF Resources" Height="100" Width="300">
<Window.Resources>
    <LinearGradientBrush x:Key="linearGradientforButton">
        <GradientStop Color="Blue" Offset="0"/>
        <GradientStop Color="White" Offset="0.5"/>
        <GradientStop Color="Cyan" Offset="1"/>
    </LinearGradientBrush>
    <Style TargetType="Button" x:Key="ButtonStyle">
        <Setter Property="Width" Value="150" />
        <Setter Property="Height" Value="40" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Top" />
        <Setter Property="Margin" Value="10" />
    </Style>
</Window.Resources>
<Grid>
    <Button Name="MyButton"
            Content="Click Me!"
            Background="{StaticResource linearGradientforButton}"
            Style="{StaticResource ButtonStyle}" />
</Grid>
</Window>



In above example, two resources are declared and both are used by one button. If you have multiple buttons in the same window, all the buttons will have access to the resources defined in window’s resources element. All the resource must be uniquely identified by x:key name inside resource dictionary. Similarly element can access those using StaticResource markup extension.

In WPF logical tree, almost every control has resource dictionaries. When any control uses resource, WPF look upward through the tree until it finds an object defined in resource with given key. In above example, Button’s background and style property uses resource from resource dictionary. So WPF will look upwards and it will find resource declared in window’s resource dictionary.

Declaring Resources in App.xaml - 

As shown in above example, if control uses resource then WPF look upwards till root object e.g. window but if the resource is not declared at root level then it will look in Application.Resources element of App.xaml file. The resources are declared in app.xaml file will be accessible to all windows inside application. So when resources are used by multiple windows, app.xaml file will be the best suitable place to declare those resources.


Let’s have a look on below code.

<Window x:Class="WpfApplication1.WPFResourcesDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WPF Resources" Height="100" Width="300">
<Grid>
    <Button Name="MyButton"
        Content="Click Me!"
        Background="{StaticResource linearGradientforButton}"
        Style="{StaticResource ButtonStyle}" />
</Grid>
</Window>

app.xaml

<Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="WPFResourcesDemo.xaml">
    <Application.Resources>
        <LinearGradientBrush x:Key="linearGradientforButton">
            <GradientStop Color="Blue" Offset="0"/>
            <GradientStop Color="White" Offset="0.5"/>
            <GradientStop Color="Cyan" Offset="1"/>
        </LinearGradientBrush>
        <Style TargetType="Button" x:Key="ButtonStyle">
            <Setter Property="Width" Value="150" />
            <Setter Property="Height" Value="40" />
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="VerticalAlignment" Value="Top" />
            <Setter Property="Margin" Value="10" />
        </Style>
    </Application.Resources>
</Application>

The output of this code will be the same as first example. In this example resources are declared in Application.Resources element of App.XAML file


Declaring resources in separate Resource Dictionary -

WPF allows you to keep your all the resources at single place called resource dictionary file. Resource dictionary file has root element called ResourceDictionary. If your application has lots of resources and you want declare those resources inside app.xaml the file will be too large and difficult to manage and also it is not good practice to place so many resources inside app.xaml. In this case you should go for separate file called ResourceDictionary. You should place different resources in multiple resources file and merge it in window. You can create multiple resource dictionary files and merge those files inside your main window. Let’s have a look on below code.

ResourceDictionary.Xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <LinearGradientBrush x:Key="linearGradientforButton">
        <GradientStop Color="Blue" Offset="0"/>
        <GradientStop Color="White" Offset="0.5"/>
        <GradientStop Color="Cyan" Offset="1"/>
    </LinearGradientBrush>
    <Style TargetType="Button" x:Key="ButtonStyle">
        <Setter Property="Width" Value="150" />
        <Setter Property="Height" Value="40" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Top" />
        <Setter Property="Margin" Value="10" />
    </Style>
</ResourceDictionary>

MainWindow.Xaml

<Window x:Class="WpfApplication1.WPFResourcesDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WPF Resources" Height="100" Width="300">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="MyResourceDictionary.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
<Grid>
    <Button Name="MyButton"
        Content="Click Me!"
        Background="{StaticResource linearGradientforButton}"
        Style="{StaticResource ButtonStyle}" />
</Grid>
</Window>

The output of this example is same as above two examples. In this example resources are placed inside separate ResourceDictionary file and in MainWindow resource dictionary merged in Window.Resources element.

Accessing Resources from code - 

WPF resources can also be created or accessed using code. Inside code we need to find resource by key name using TryFindResoruce Method or FindResource method. Both methods used to find resources from resource dictionary the only difference is FindResource method will throw an exception if resource not found while TryFindResource Method will return null. Let’s have a look on below code.

private void MyButton_Click(object sender, RoutedEventArgs e)
{
    MyButton.Background = (Brush)TryFindResource("linearGradientforButton");
}

In above code snippet, TryFindResource method will try to find “linearGradientforButton” resource from dictionary if found assign to background property and if not found then assign null to background property.


Hope you liked this article on WPF Resources. Please feel free to write feedback/comments in comment section below.


See also –