top button
Flag Notify
    Connect to us
      Site Registration

Site Registration

ListView, data binding and ItemTemplate in XAML ?

+4 votes
769 views

it's about separating data from layout. So, let's try binding some data to a ListView:

using System;
using System.Collections.Generic;
using System.Windows;

namespace WpfTutorialSamples.ListView_control
{
        public partial class ListViewDataBindingSample : Window
        {
                public ListViewDataBindingSample()
                {
                        InitializeComponent();
                        List<User> items = new List<User>();
                        items.Add(new User() { Name = "John Doe", Age = 42 });
                        items.Add(new User() { Name = "Jane Doe", Age = 39 });
                        items.Add(new User() { Name = "Sammy Doe", Age = 13 });
                        lvDataBinding.ItemsSource = items;
                }
        }

        public class User
        {
                public string Name { get; set; }

                public int Age { get; set; }
        }
}

We populate a list of our own User objects, each user having a name and an age. The data binding process happens automatically as soon as we assign the list to the ItemsSource property of the ListView, but the result is a bit discouraging:

A simple ListView control, using data binding

Each user is represented by their type name in the ListView. This is to be expected, because .NET doesn't have a clue about how you want your data to be displayed, so it just calls the ToString() method on each object and uses that to represent the item.

We can use that to our advantage and override the ToString() method, to get a more meaningful output. Try replacing the User class with this version:

public class User
{
        public string Name { get; set; }

        public int Age { get; set; }

        public override string ToString()
        {
                return this.Name + ", " + this.Age + " years old";
        }
}

A simple ListView control, using data binding and a ToString method on the source object

This is a much more user friendly display and will do just fine in some cases, but relying on a simple string is not that flexible. Perhaps you want a part of the text to be bold or another color? Perhaps you want an image? Fortunately, WPF makes all of this very simple using templates.

ListView with an ItemTemplate

WPF is all about templating, so specifying a data template for the ListView is very easy. In this example, we'll do a bunch of custom formatting in each item, just to show you how flexible this makes the WPF ListView.

Download sample

<Window x:Class="WpfTutorialSamples.ListView_control.ListViewItemTemplateSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ListViewItemTemplateSample" Height="150" Width="350">
    <Grid>
                <ListView Margin="10" Name="lvDataBinding">
                        <ListView.ItemTemplate>
                                <DataTemplate>
                                        <WrapPanel>
                                                <TextBlock Text="Name: " />
                                                <TextBlock Text="{Binding Name}" FontWeight="Bold" />
                                                <TextBlock Text=", " />
                                                <TextBlock Text="Age: " />
                                                <TextBlock Text="{Binding Age}" FontWeight="Bold" />
                                                <TextBlock Text=" (" />
                                                <TextBlock Text="{Binding Mail}" TextDecorations="Underline" Foreground="Blue" Cursor="Hand" />
                                                <TextBlock Text=")" />
                                        </WrapPanel>
                                </DataTemplate>
                        </ListView.ItemTemplate>
                </ListView>
        </Grid>
</Window>

 

posted Feb 4, 2016 by Jdk

  Promote This Article
Facebook Share Button Twitter Share Button LinkedIn Share Button


Related Articles

Data Binding

Data Binding is the process of taking some data and associating it to visual elements on user interface (UI).

Overview of Data Binding

We will take any object and with their properties present each instance of object in collection on screen to user in “Grid “like fashion. We get to create a little template of how each individual instance of object is represented in the user interface .The “ListView” is also same but it works in single column fashion.

Create a Project in Visual Studio 2015

In order to perform data binding , you need to create a project in Visual Studio 2015, steps are simple:

  1. Select “Universal” as shown by arrow.
  2. Select “Blank App” as shown in circle.
  3. Name your solution, for instance “BindDataExample“.

binddataexample

Designer Window

A designer window will open once you create the project with name”MainPage.xaml“. in this window there is a designer surface and you can also write your XAML code …now for instance we select our object a “Book” and in order to perform data binding simply create a user interface in XAML . The code is shown in the following image in rectangle sharpe.

Designer Window

Create Data Model

  1. Go to “Solution Explorer” shown by circle.
  2. Right click the “BindDataExample” shown by arrow.
  3. Add new folder, name it “Models” shown by circle.

Create Data Model

Create C# class in Models Folder

  1. Go to Models folder.
  2. Right click and select add new item.
  3. Select Class and name it “Book.cs“.

C# class

Book Class with Properties

Once you perform all the above mentioned tasks, there will be a c# class open for us and our object which in this case is a book, we can create its class and define its properties in that very C# class we have.

  1. Create a class “Book“.
  2. Define its properties.
  3. Copy the C# code in red rectangular box.

Book

Creating New Instances & Add in Collection

After you created your Book class and set its properties, now its time to create instances of your class and populate it into a collection, list of book. We will generate another class , name it “BookManager” in the same file, for this purpose. And then return the list to caller. The following code will help you out.

BookManager

Add GridView, Bind to data from BookManager Class

Our next step is after we created the instances, storing them in collection is to bind the data in GridView from that very class. For this we will return to our “MainPage.xaml” and create a template that how each individual item will appear on the screen. The template code is in red box . 

MainPage.xaml

Add XAML namespace

In order to reference the class in XAML, we need to reference its namespace in XAML. Here you go, shown by red arrow.

xaml namespace

Create Public Property in MainPage.xaml.cs

After we create the template, our next step will be to create a public property in “mainpage.xaml.cs “and populate it with Books.

  1. Add public property as shown in circular region.
  2. Make sure you add a namespace if it is not there as shown by arrow.
  3. Initialize it with “Books=BookManager.GetBooks();.”, this will return list of books.

public property

Run your Application.

After completion of all the steps, run you application and the final result will be shown something like the following,

bind your application

Working on Alignment

You can change the alignment and margin again. Here's a simple step to do,

Alignment

Overview

In nutshell, the alignment will make display much better.

READ MORE

Data binding is that robust way to connect your properties with any data source. In this tutorial we will dig into class binding step-by-step. If you are already familiar with class binding then you can skip this tutorial.

Class Binding

Class Binding provides high-level access to the definition of a binding that connects the properties of the binding target objects and any data source (for example, a database, an XML file, or any object that contains data). It is so strong and easy that one can easily interact with data within the application and can bind the data with any of the properties of the objects.

Let's Dig

To understand class binding we will go through the following procedure for easy comprehension. First we will create a simple Windows 8.1 Silverlight application. This application will show the data of the object bound with the items of the Listbox.

blank app
Fig:1. Creating the Project.

Give the project a good name. Once you have created the project, you will see the following screen:

create project

Now for the class binding, we will create a class first, in this case I will create a class named Country:

class name country

We will add some Plain Old CLR Objects (POCOs) to our class:

class

After creating the class, we will move the MainPage.xaml and will add the Listbox to the Content Panel as in the following:

main page

Then, it would be noteworthy to specify how to customize the items in the listbox, so customizing the listbox item Template and as our class has three data members, we will add three controls to each item, in this case I will use two textblocks and one checkbox for the bool data member.



You can see in this figure that the checkbox and the textblocks are being bound with the data members of the class (Country), so basically the XAML code that actually binds the class is as in the following:

  1. <CheckBox IsChecked="{Binding IsMember}"/>  
  2. <TextBlock Grid.Column="1" Name="CountryName" Text="{Binding CountryName}"/>  
  3. <TextBlock Grid.Column="2" Name="txtShortName" Text="{Binding ShortName}"/>   

Now to load some dummy data into the Country class we will create the load event and add some data on the load event of the Page, for that we will need to create the list and add some objects of class Country to that list and then make this list the source for the listbox. Here is the C# code of that:

cs code

And now you can run the project, we are done with the simple class binding.

demo

READ MORE
 

The great thing about XAML is that you can easily change the foreground colour of controls, such as a TextBlock, to be exactly what you want it to be. Whether that is through the built-in colour names or a HEX colour is completely your choice.

 

However there may be times when you simply wish to change the colour of a control dependent on the value that it is displaying. In this example we will be using a TextBlock that has it's Text value assigned to it using data context binding.

 

MainPage.xaml

<Page        
    x:Class="MainPage"    
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
    xmlns:local="using:TestProject"    
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"        
    mc:Ignorable="d">    
    <Page.Resources>    
        <DataTemplate x:Key="listViewItems">    
            <StackPanel>    
                <TextBlock        
                    Margin="5,5,5,5"        
                    Text="{Binding Name}"        
                    Style="{StaticResource BaseTextBlockStyle}"/>    
                <TextBlock        
                    Margin="5,5,5,5"        
                    Text="{Binding Ripeness}"        
                    Style="{StaticResource BaseTextBlockStyle}"/>    
            </StackPanel>    
        </DataTemplate>    
    </Page.Resources>    
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">    
        <ListView        
            x:Name="listViewTest"        
            Margin="5,5,5,5"        
            VerticalAlignment="Center"        
            HorizontalAlignment="Center"        
            ItemsSource="{Binding}"        
            SelectionMode="None"        
            IsItemClickEnabled="False"        
            ItemTemplate="{StaticResource listViewItems}"        
            ContainerContentChanging="listViewUpdated"></ListView>    
        <TextBlock        
            x:Name="listViewNoItems"        
            Margin="5,5,5,5"        
            VerticalAlignment="Center"        
            HorizontalAlignment="Center"        
            Text="There are no fruits in your list to display!"        
            Style="{StaticResource BaseTextBlockStyle}"        
            Visibility="Collapsed"/>    
        <Button        
            Width="150"        
            Height="50"        
            Margin="20"        
            VerticalAlignment="Center"        
            HorizontalAlignment="Right"        
            Content="Clear fruit"        
            Click="clearFruitBasket"/>    
    </Grid>    
</Page>  

 

MainPage.xaml.cs


using System.Collections.ObjectModel;    
using Windows.UI.Xaml;    
using Windows.UI.Xaml.Controls;    
namespace CSharpCornerTestProject     
{    
    public class Fruit     
    {    
        public string Name    
        {    
            get;    
            set;    
        }    
        public string Ripeness     
        {    
            get;    
            set;    
        }    
    }    
    public sealed partial class MainPage: Page     
    {    
        private ObservableCollection < Fruit > fruitList = new ObservableCollection < Fruit > ();    
        public MainPage()     
        {    
            this.InitializeComponent();    
            fruitList.Add(new Fruit()    
            {    
                Name = "Apple", Ripeness = "Ok"    
            });    
            fruitList.Add(new Fruit()    
            {    
                Name = "Banana", Ripeness = "Bad"    
            });    
            fruitList.Add(new Fruit()    
            {    
                Name = "Kiwi", Ripeness = "Rotten"    
            });    
    
            listViewTest.ItemsSource = fruitList;    
        }    
        private void listViewUpdated(ListViewBase sender, ContainerContentChangingEventArgs args) {    
            if (listViewTest.Items.Count == 0)     
            {    
                listViewNoItems.Visibility = Visibility.Visible;    
                listViewTest.Visibility = Visibility.Collapsed;    
            }     
            else     
            {    
                listViewNoItems.Visibility = Visibility.Collapsed;    
                listViewTest.Visibility = Visibility.Visible;    
            }    
           }    
        private void clearFruitBasket(object sender, RoutedEventArgs e)    
        {    
            // clear the fruit list!        
            if (fruitList != null) fruitList.Clear();    
        }    
    }    
}

As I stated above, this is the code base that we used in my previous article about displaying a message once a ListView control no longer has any items in it. We will slightly modify this now so that the ripeness of the fruit in our fruit basket is colour-coded depending on its value.

 

The first thing we need to do is to create a convertor class for us to use when binding data to the list view. This is a very simple affair and just requires you to add a new "Class file" to your project.

 

FruitBasketConvertor.cs

using System;    
using Windows.UI;    
using Windows.UI.Xaml.Data;    
using Windows.UI.Xaml.Media;    
namespace CSharpCornerTestProject.Convertors     
{    
    public class fruitBasketRipenessForegroundConvertor: IValueConverter    
    {    
        public object Convert(object value, Type targetType, object parameter, string language)    
        {    
            string ripeness = (value as string);    
            if (ripeness == "Ok") return new SolidColorBrush(Colors.ForestGreen);    
            else if (ripeness == "Bad") return new SolidColorBrush(Colors.OrangeRed);    
            else if (ripeness == "Rotten") return new SolidColorBrush(Colors.DarkRed);    
            // default return value of lime green      
            return new SolidColorBrush(Colors.LimeGreen);    
        }    
        public object ConvertBack(object value, Type targetType, object parameter, string language)    
        {    
            throw new NotImplementedException();    
        }    
    }    
}  

That is all there is to our file, just those 30 lines. Do take note, however, that we have placed the convertors under their own namespace, CSharpCornerTestProject.Convertors.

 

Using convertors isn't all as daunting as it seems. You create your own custom class, making sure that it derives from IValueConvertor.  Then all we need are two functions.

public object Convert(object value, Type targetType, object parameter, string language)  
{  
    // your convertor code goes here    
}  
public object ConvertBack(object value, Type targetType, object parameter, string language)   
{  
    // your convert back code goes here    
}

The Convert function takes the raw value of your binding and allows you to access anything associated with that, whether it is a class, a string, or anything of your choosing.

 

The ConvertBack function is generally not used all that often and so in our example we are leaving it asthrow new NotImplementedException();. Its main use would be if you wanted to convert the value back to its original state.

 

Returning to the Convert function, this is very simple and there isn't all that much to it at all. All we do here is take the object value and store it into our string variable, ripeness.  

public object Convert(object value, Type targetType, object parameter, string language)   
{  
    string ripeness = (value as string);  
    if (ripeness == "Ok") return new SolidColorBrush(Colors.ForestGreen);  
    else if (ripeness == "Bad") return new SolidColorBrush(Colors.OrangeRed);  
    else if (ripeness == "Rotten") return new SolidColorBrush(Colors.DarkRed);  
    // default return value of lime green      
    return new SolidColorBrush(Colors.LimeGreen);  
}   

Since we have different forms of Ripeness in our Fruit class, we have three separate if statements to determine which colour we should return for our Foreground colour.

 

When converting a Foreground (or Background) XAML member, it expects a SolidColorBrush to be returned and so that is what we are giving it.

 

That is everything that we need to do for the code side of things with our convertor, the next step is much simpler and only requires us to add three new lines of code to the existing MainPage.xaml file that we have.

 

In our Page control, we need to add a new member, highlighted in bold Green.

<Page  
x:Class="MainPage"  
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
    xmlns:local="using:rTestProject"  
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
    xmlns:utils="using:TestProject.Convertors"  
mc:Ignorable="d">  

This will allow us to access the custom convertor class that we just created in FruitBasketConvertor.cs.

 

Now that we have done that, we need to add our convertor function as a page resource and provide it a key. This will allow us to access it when using the binding convertor. Once again, the addition is highlighted in bold Green.

<Page.Resources>  
    <utils:fruitBasketRipenessForegroundConvertor x:Key="ripenessConvertor"/>  
    <DataTemplate x:Key="listViewItems">  
        <StackPanel>  
            <TextBlock      
                Margin="5,5,5,5"      
                Text="{Binding Name}"      
                Style="{StaticResource BaseTextBlockStyle}"/>  
            <TextBlock      
                Margin="5,5,5,5"      
                Text="{Binding Ripeness}"      
                Style="{StaticResource BaseTextBlockStyle}"/>  
        </StackPanel>  
    </DataTemplate>  
</Page.Resources>

Now that we have given our convertor a key, we can access it anywhere in the MainPage.xaml file when we are binding items. We just have one last thing to do now, that is to add a Foreground member to the TextBlock control that is telling us how ripe our fruit is.

<TextBlock    
    Foreground="{Binding Ripeness, Converter={StaticResource ripenessConvertor}}"    
    Margin="5,5,5,5"    
    Text="{Binding Ripeness}"    
    Style="{StaticResource BaseTextBlockStyle}"/>    

That is everything that we need to do to start dynamically changing the foreground colour of our XAML controls dependent on what the value they're displaying is. If you run the app your fruit basket should now show the Ripeness of each fruit in the three different colours that we assigned earlier on whilst creating our convertor function.

 

READ MORE

In this article you will learn how to create and use a CustomResource in XAML.

 

  1. Open a new Visual C# windows project.
     
  2. Add a new class named say CustomResourceTest.cs in the project folder.

    CustomResourceTest.cs
     
  3. Derive this class from CustomXamlResourceLoader Class(Case sensitive) like below:

    CustomXamlResourceLoader Class
     
  4. You will get a Namespace not found error. Resolve it by using Windows.UI.Xaml.Resources Namespace.

    Windows.UI.Xaml.Resources
     
  5. Override the GetResource Member of the parent class as below. Use the intellisense to select the member.

    getresource

    getresource1
     
  6. Replace the Code inside the GetResource Method as: (this is just a simple example). We are returning a text. We plan to show this text inside a TextBlock’s Text Property.

    TextBlock
     
  7. Inside the MainPage.cs . Add the following line of code inside the MainPage Constructor to reference the CustomResouceTest.cs Class from the Page’s XAML.

    MainPage

    Correct the NameSpace not found error by resolving it.
     
  8. Now go to the MainPage.xaml Page and Add a TextBlock as follows. Notice the Text property of the TextBlock.

    MainPage.xaml
     
  9. This results in the following output when you save, build and run the project.

    run
     
  10. What is happening here?
     
    • We created a CustomResourceClass where we inherited the Class called CustomXamlResourceLoader.
    • We override the GetResourceProperty. Don’t focus on the parameters of this method for now.
    • We replaced the code inside this method by simply returning a text.
    • To access this CustomResource from XAML we have to define the CustomXamlResourceLoader. Current property to the new instance of the Class we created. We have to do this inside the Constructor of the Codebehind page where we want to use the CustomResource.
    • We then simply assigned the value of the Text property of the textblock to the CustomResource as seen on Step 8.

Example 2:

  1. Now we will try a different example where we want to display the Text of the TextBlock based on the value we pass on. Change the text of the Mainpage.xaml as:

    Mainpage.xaml 2
     
  2. The 'sayHello' string is passed as a string to the CusomResourceTest.cs class as ResourceID parameter of the overridden class. This will be more clear as you see in the next step.
     
  3. In the CustomResourceTest.cs class , change the code as follows:

    CustomResourceTest.cs2
     
  4. The thing to understand is how we pass the ResourceID from the Text Property of the TextBlock. It is passed as the resourceID parameter. So, based on the ResourceID, we return the appropriate text we want to display on the output screen.
     
  5. So now we get output as.
  6. If we change the text property as sayByeBye.

    sayByeBye
     
  7. We get the following output:
     
READ MORE

I am building a website in XAML (Silverlight) and trying to put prototype samples together to see what can be done in Silverlight and what obstacles will I face in building samples that can easily be done in ASP.NET 2.0. One piece of this was to create an animated banner that shows some ads and give text animations such as changing colors, rotation, and size.

In a graphics designer, you create layers and frames and give them a time interval to load a different layer to create an animated graphics. Fortunately, this functionality is built-in in WPF and XAML. Now, I don't have to create different layers or frames. I can simply create a text and apply animation or transformation on the text and WPF will take care for me. 

I have a banner looks like Figure 1.

 

AnimatedBanImg1.jpg
Figure 1. Initial banner

As you can see from Figure 1, I have four text blocks loaded in the banner and two of them are with a gradient background. I would apply four different animations on these four text blocks. I would change the gradient background of first text block, change the foreground color of second text block, change the width of third text block, and rotate the fourth text block. The running banner will look like Figure 2 and repeat this behavior indefinitely.

 

AnimatedBanImg2.jpg

Figure 2. Animated text banner

The magic begins within the Storyboard tag of XAML. Within the Storyboard tag, we can use animations such as double animation, color animation, point animation, or transformation.

<TextBlock.Triggers>

      <EventTrigger RoutedEvent="FrameworkElement.Loaded">

            <BeginStoryboard>

                  <Storyboard>

                                         

                  </Storyboard>

            </BeginStoryboard>

      </EventTrigger>

</TextBlock.Triggers>

The DoubleAnimation tag is used to apply transparency on controls. The following code shows the syntax of the DoubleAnimation. The TargetName is the name of the control such as a TextBlock. The From and To attributes is the range for transparency range between 1.0 and 0.0 where 1.0 is fully opaque and 0.0 is fully transparent.  The RepeatBehavior is Forever means the animation will repeat forever.

<DoubleAnimation

      Storyboard.TargetName="TB"                                 Storyboard.TargetProperty="Opacity"

      From="1.0" To="0.0" Duration="0:0:5"

      AutoReverse="True" RepeatBehavior="Forever" />

The following code shows how to user color animation using the ColorAnimation tag, which takes TargetName as name of the brush and TargetProperty as Color. The From and To attributes are starting and end colors.

<ColorAnimation

Storyboard.TargetName="SB"

Storyboard.TargetProperty="Color"

From="Pink" To="SteelBlue" Duration="0:0:5"

AutoReverse="True" RepeatBehavior="Forever" />

The following code usage double animation to set the transformation angle of the text box to rotate a text block.

<DoubleAnimation

Storyboard.TargetName="MyRT"

      Storyboard.TargetProperty="(RotateTransform.Angle)"

      From="0.0" To="360" Duration="0:0:10"

RepeatBehavior="Forever" />

Download the attached XAML file for more details and complete XAML code.  

Here is a listing of complete XAML code:

<Window

      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

      x:Class="AnimatedBanner.Window1"

      x:Name="Window"

      Title="Window1"

      Width="396" Height="492"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d" Foreground="#FFF15151" SnapsToDevicePixels="True" >

 

      <Grid x:Name="LayoutRoot">

            <Rectangle Margin="66,42,152,20" Stroke="#FF000000" RadiusX="0"RadiusY="0">

                  <Rectangle.Fill>

                        <LinearGradientBrush x:Name="MRGB" EndPoint="0.5,1"StartPoint="0.5,0">

                              <GradientStop Color="#FF000000" Offset="0"/>

                              <GradientStop Color="#FF5E0805" Offset="0.478"/>

                        </LinearGradientBrush>

                  </Rectangle.Fill>            

            </Rectangle>

           

      <TextBlock x:Name="TB" Margin="75,49,161,0" FontFamily="Book Antiqua"FontSize="24" FontWeight="Bold" TextWrapping="Wrap" Foreground="#FFF9F4F4"TextAlignment="Center" Height="56" VerticalAlignment="Top" ><TextBlock.Background>

                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">

                              <GradientStop Color="#FF000000" Offset="0"/>

                              <GradientStop Color="#FFD600FF" Offset="1"/>

                        </LinearGradientBrush>

                  </TextBlock.Background>

                  <TextBlock.Triggers>

                        <EventTrigger RoutedEvent="FrameworkElement.Loaded">

                              <BeginStoryboard>

                                    <Storyboard>

                                          <DoubleAnimation

                                                Storyboard.TargetName="TB"

                                                Storyboard.TargetProperty="Opacity"

                                                From="1.0" To="0.0"Duration="0:0:5"

                                                AutoReverse="True"RepeatBehavior="Forever" />

                                    </Storyboard>

                              </BeginStoryboard>

                        </EventTrigger>

                  </TextBlock.Triggers><Run FontFamily="Cambria" FontSize="20"Text="Need help on a .NET Project? "/></TextBlock>

            <TextBlock x:Name="TB2" Margin="75,225,161,131" FontFamily="Book Antiqua" FontSize="24" FontWeight="Bold" TextWrapping="Wrap" Foreground="#FFF9F4F4"TextAlignment="Center"><TextBlock.Background>

                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">

                              <GradientStop Color="#FF000000" Offset="0"/>

                              <GradientStop Color="#FF00FF4D" Offset="1"/>

                        </LinearGradientBrush>

                  </TextBlock.Background>

                  <LineBreak/><Run FontFamily="Cambria" FontSize="20"Foreground="#FF97ECC3" Text="Let our experts help you."/>

                  <TextBlock.Triggers>

                        <EventTrigger RoutedEvent="FrameworkElement.Loaded">

                              <BeginStoryboard>

                                    <Storyboard/>

                              </BeginStoryboard>

                        </EventTrigger>

                  </TextBlock.Triggers>

                  </TextBlock>

     

           

            <!-- Color Animation Sample. Changes color from Pink to SteelBlue -->

            <TextBlock

              x:Name="TB4"

              Margin="75,120,161,0" FontSize="16" FontWeight="Bold"VerticalAlignment="Top"

              Height="100" Text="Silverlight, C#, ASP.NET, WPF, WCF"TextWrapping="WrapWithOverflow" TextAlignment="Center">

              <TextBlock.Foreground>

                <SolidColorBrush x:Name="SB" Color="Pink" />

              </TextBlock.Foreground>

 

              <!-- Animates the text block's color. -->

              <TextBlock.Triggers>

                <EventTrigger RoutedEvent="FrameworkElement.Loaded">

                  <BeginStoryboard>

                    <Storyboard>

                        <!-- Use ColorAnimation with TargetProperty as Color and TargetName as brush being used

                        to draw the text -->

                      <ColorAnimation

                        Storyboard.TargetName="SB"

                        Storyboard.TargetProperty="Color"

                        From="Pink" To="SteelBlue" Duration="0:0:5"

                        AutoReverse="True" RepeatBehavior="Forever" />

                    </Storyboard>

                  </BeginStoryboard>

                </EventTrigger>

              </TextBlock.Triggers>

            </TextBlock>

 

 

            <!-- Text Rotation Sample -->

            <TextBlock

              x:Name="TB5"

              Margin="97,0,183,41"

              FontSize="18" FontWeight="Bold" Foreground="Green"VerticalAlignment="Bottom" Height="60"><TextBlock.RenderTransform>

                <RotateTransform x:Name="MyRT" Angle="0" CenterX="30"CenterY="25"/>

              </TextBlock.RenderTransform><!-- Animates the text block's rotation. --><TextBlock.Triggers>

                <EventTrigger RoutedEvent="FrameworkElement.Loaded">

                  <BeginStoryboard>

                    <Storyboard>

                        <!-- Use DoubleAnimation with TargetProperty as RotateTransform.Angle

                              and TargetName as name of the RotateTransform being used to rotate the text -->

                      <DoubleAnimation

                        Storyboard.TargetName="MyRT"

                        Storyboard.TargetProperty="(RotateTransform.Angle)"

                        From="0.0" To="360" Duration="0:0:10"

                        RepeatBehavior="Forever" />

                    </Storyboard>

                  </BeginStoryboard>

                </EventTrigger>

              </TextBlock.Triggers><Run FontSize="20" Text="Contact Us"/></TextBlock>

           

            <!-- Author TextBlok -->

     

      </Grid>

</Window>

READ MORE

While analyzing some controls used for touch devices I found this effective and easy logic for touch control and slow finishing action after touch leaves. Normally in touch devices we like to have control of an application with very smooth touch interaction. We also expect some slow finish of the action, like if we tap and wipe a control then it will move some distance and stay. So I found this logic to do that in an effective manner.

Platform support this approach

  • WPF
  • Windows Stores (WinRT)
  • Windows Phones 8 

Concept behind the approach

In my logic I have handled the manipulation of the data to the control. Using the manipulation of the data, I reset the matrix value of the control as desired. For slow finishing, I used a timer that enables the control for slower and smooth finishing actions after touch leaves.

XAML Code snippet behind the approach

<Button x:Class="TouchApplication.SmoothestTouchControl"

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

  <Grid>

  </Grid>

</Button>

<Window x:Class="TouchApplication.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="MainWindow" Height="350" Width="525"

xmlns:local="clr-namespace:WpfApplication8">

  <Grid >

    <local:SmoothestTouchControl IsManipulationEnabled="True"

    RenderTransform="0.9 0 0 0.9 100 100" />

 

    <local:SmoothestTouchControl IsManipulationEnabled="True"

    RenderTransform="0.9 0 0 0.9 100 100" />

 

    <local:SmoothestTouchControl IsManipulationEnabled="True"

    RenderTransform="0.9 0 0 0.9 100 100" />

 

    <local:SmoothestTouchControl IsManipulationEnabled="True"

    RenderTransform="0.9 0 0 0.9 100 100" />

 

    <local:SmoothestTouchControl IsManipulationEnabled="True"

    RenderTransform="0.9 0 0 0.9 100 100" /

  </Grid>

</Window>

C# code snippet behind the approach
 

// Use required name space  using System;

using System.Linq;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Input;

using System.Windows.Media;

 

namespace TouchApplication

{

    /// Interaction logic for SmoothestTouchControl.xaml

 

    public partial class SmoothestTouchControl : Button

    {

        int i = 0; // Iteration count for slower animation to end

        UIElement uiElement = null; // contains current control

        MatrixTransform matrixTransform = null; // contains Matrix transform

        Matrix uiElementMatrix = new Matrix(); // contains Matrix of the UIElement

        ManipulationDelta manipulationDelta = null; // contains data of Manipulation

        Point centerPoint = new Point(); // contains center point of the element

        System.Windows.Forms.Timer smoother = new System.Windows.Forms.Timer(); // Animater that slow down the action after touch leave

        public SmoothestTouchControl()

        {

            smoother.Interval = 1; // Inverval for animater

            smoother.Tick += smoother_Tick; // hook event to animation

        }

        // override manupulation starting to reset the Z order to get the current touched UI element a top element

        protected override void OnManipulationStarting(ManipulationStartingEventArgs args)

        {

            args.ManipulationContainer = App.Current.MainWindow; // Get the parent window

 

            var frameworkElement = args.Source as FrameworkElement; // Get the current touched element

 

            var panel = frameworkElement.Parent as Panel; // Get parent element to have the children collection

 

            for (int i = 0; i < panel.Children.Count; i++) // Iterate the children collection to reset the Z order

            {

                Panel.SetZIndex(panel.Children[i], panel.Children[i] == frameworkElement ? panel.Children.Count : i);

            }

            args.Handled = true; // Get handled true

 

            base.OnManipulationStarting(args); // Call base for original action

        }

        // override manipulation delta for transform actions

        protected override void OnManipulationDelta(ManipulationDeltaEventArgs args)

        {

            uiElement = args.Source as UIElement; // Get the current touched element

            matrixTransform = uiElement.RenderTransform as MatrixTransform; // Get MatrixTransform of the element

            uiElementMatrix = matrixTransform.Matrix; // Get Matrix of the element

            manipulationDelta = args.DeltaManipulation; // Get delta manipulation of the touch action

            centerPoint = args.ManipulationOrigin; // Get center point of the manipulation

 

            uiElementMatrix.RotateAt(manipulationDelta.Rotation, centerPoint.X, centerPoint.Y); // Rotate the ccontrol acccording to manipulation

            uiElementMatrix.ScaleAt(manipulationDelta.Scale.X, manipulationDelta.Scale.Y, centerPoint.X, centerPoint.Y);// Scale the ccontrol acccording to manipulation

            uiElementMatrix.Translate(manipulationDelta.Translation.X, manipulationDelta.Translation.Y); // Move the ccontrol acccording to manipulation

 

            matrixTransform.Matrix = uiElementMatrix; // Reset the updated matrix to the element matrix

            args.Handled = true; // Get handled true

            base.OnManipulationDelta(args); // Call base for original action

        }

        // override manipulation completed to start slower finish of the touch action

        protected override void OnManipulationCompleted(ManipulationCompletedEventArgs e)

        {

            base.OnManipulationCompleted(e); // Call base for original action

            smoother.Interval = 1; // reset the interval of the slower finish action

            i = 10; // Reset the iterator of the slower finish

            smoother.Start(); // Start animation for slower finish

        }

 

        // slowe finish animater logic

        void smoother_Tick(object sender, EventArgs e)

        {

            i--; // for slow finish action

 

            smoother.Interval = smoother.Interval + 2; // increase interval for integrated slow finish

 

            if (smoother.Interval > 25) // Check for dezire interval

                smoother.Stop(); // Stop the animation

 

            if (manipulationDelta.Rotation != 0) // Check if the control atually in rotation

            {

                uiElementMatrix.RotateAt(manipulationDelta.Rotation - (i > 0 ? i : 1), centerPoint.X, centerPoint.Y); // keep rotation using iterated value

            }

            uiElementMatrix.Translate(manipulationDelta.Translation.X - (i > 0 ? i : 0), manipulationDelta.Translation.Y - (i > 0 ? i : 0)); // keep moving using iterated value

            matrixTransform.Matrix = uiElementMatrix; // reset the updated matrix to the element matrix  

        } 

    }

}

READ MORE

We can use the Arc XAML element to draw arcs in XAML. Besides drawing arcs using the Arc element, we can also use the ArcSegment element. The ArcSegment is useful when an arc becomes a part of a graphics path or a larger geometric object.

 

In this article, we will see how to use the ArcSegment to draw arcs in XAML and WPF.

 

The ArcSegment object represents an elliptical arc between two points. The ArcSegment class has the five properties Point, Size, SweepDirection, IsLargeArc and RotationAngle. 

 

  • The Point property represents the endpoints of an arc. 
  • The Size property represents the x and y radiuses of an arc. 
  • The SweepDirection property specifies whether an arc sweep direction is clock wise or counter clock wise. 
  • The IsLargeArc property returns true if an arc is greater than 180 degrees. 
  • The RotationAngle property represents the angle by which an ellipse is rotated about the x-axis.

 

 

The following figure provided by the MSDN documentation shows these property values and their results.

Graphics-Arc.jpg

<ArcSegment Size="300,50" RotationAngle="30" 
            IsLargeArc="True" SweepDirection="CounterClockwise"  Point="200,100" />

A Path object is used to draw an arc by setting a PathGeomerty as Path.Data. The following code snippet creates a Path and sets a ArcSegment as a part of PathFigure.Segments.

<Path Stroke="Black" StrokeThickness="1">
    <Path.Data>
        <PathGeometry>
            <PathGeometry.Figures>
                <PathFigureCollection>
                    <PathFigure StartPoint="0,100">
                        <PathFigure.Segments>
                            <PathSegmentCollection>
                                <ArcSegment Size="300,50" RotationAngle="30"
                                            IsLargeArc="True"
                                            SweepDirection="CounterClockwise"
                                            Point="200,100" />
                            </PathSegmentCollection>
                        </PathFigure.Segments>
                    </PathFigure>
                </PathFigureCollection>
            </PathGeometry.Figures>
        </PathGeometry>
    </Path.Data>
</Path>

The output looks like Figure 1.

 

ArcSegment-1.jpg

Figure 1

We can paint an arc by simply painting the path using the Fill method. The following code snippet has changes in it from the previous code that fills a path. 

<Path Stroke="Black" StrokeThickness="1" Fill="Yellow">

The new output looks like Figure 2.

 

ArcSegment-Filled.jpg

Figure 2

The following code snippet creates an arc segment shown in Figure 2 dynamically.

private void CreateArcSegment()
{
    PathFigure pthFigure = new PathFigure();
    pthFigure.StartPoint = new Point(0, 100); 

    ArcSegment arcSeg = new ArcSegment();
    arcSeg.Point = new Point(200, 100);
    arcSeg.Size = new Size(300,50);
    arcSeg.IsLargeArc = true;
    arcSeg.SweepDirection = SweepDirection.Counterclockwise;
    arcSeg.RotationAngle = 30;   

    PathSegmentCollection myPathSegmentCollection = new PathSegmentCollection();
    myPathSegmentCollection.Add(arcSeg); 

    pthFigure.Segments = myPathSegmentCollection; 

    PathFigureCollection pthFigureCollection = new PathFigureCollection();
    pthFigureCollection.Add(pthFigure); 

    PathGeometry pthGeometry = new PathGeometry();
    pthGeometry.Figures = pthFigureCollection; 

    Path arcPath = new Path();
    arcPath.Stroke = new SolidColorBrush(Colors.Black);
    arcPath.StrokeThickness = 1;
    arcPath.Data = pthGeometry;
    arcPath.Fill = new SolidColorBrush(Colors.Yellow); 

    LayoutRoot.Children.Add(arcPath);
}

 

READ MORE
...