الاثنين، 30 مايو 2011

Free Silverlight 4.0 Seminar ( 3/6/2011)



What is Silverlight?
How does it relate to other client-side technologies?
How important is it?
Silverlight app development walk-through


Speaker : Ahmed EL Bohoty

يوم الجمعة

3/6


WPF User Control

The role that user controls and custom controls play in WPF is quite different than in other technologies. In other technologies, custom controls are often created simply to get a nonstandard look. But WPF has many options for achieving nonstandard-looking controls without creating brand-new controls. You can completely restyle built-in controls with WPF’s style and template mechanisms. Or you can sometimes simply embed complex content inside built-in controls to get the look you want.
In other technologies, a Button containing an Image or a TreeView containing ComboBoxes might necessitate a custom control, but not in WPF! (That’s not to say that there are fewer opportunities for selling reusable components. It just means you’ve got more implementation options.
Therefore, the decision to create a user control or custom control should be based on the APIs you want to expose rather than the look you want to achieve. If no existing control has a programmatic interface that naturally represents your concept, go ahead and create a user control or custom control. The biggest mistake people make with user controls and custom controls is creating one from scratch when an existing one can suffice.


Steps
1-      Add new Item > Add User control
2-      We want to make file browse control > add textbox   and Button control
      <DockPanel>
            <Button x:Name="theButton" DockPanel.Dock="Right" Height="45" Width="74">
                Browse...Button>
            <TextBox x:Name="theTextBox" Background="Yellow"  Height="37" Width="200" />
           
        DockPanel>

3-      You can write your suitable code into button to allow user to open dialogue and it’s easy for you to implement.
4-      In Main Window > declare the xmlns attribute
                        xmlns:my="clr-namespace:WpfApplication3"

Here ‘s the final code
<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:WpfApplication3"
        Title="MainWindow" Height="350" Width="525" xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared" xmlns:navigation="http://schemas.actiprosoftware.com/winfx/xaml/navigation" xmlns:docking="http://schemas.actiprosoftware.com/winfx/xaml/docking" xmlns:editors="http://schemas.actiprosoftware.com/winfx/xaml/editors" xmlns:ribbon="http://schemas.actiprosoftware.com/winfx/xaml/ribbon">
    <Grid>
        <StackPanel Margin="20">
            <my:UserControl1 Height="67" Width="278" />
        StackPanel>
    Grid>
Window>

الجمعة، 27 مايو 2011

Triggers in WPF


Triggers
Triggers have a collection of Setters just like Style (and/or collections of Trigger Actions). But whereas a Style applies its values unconditionally, a trigger performs its work based on one or more conditions.

Recall that there are three types of triggers:
  • Property Triggers get active, when a property gets a specified value.
  • Event Triggers get active, when a specified event is fired.
  • Data Triggers get active, when a binding expression reaches a specified value.
FrameworkElement, Style, DataTemplate, and ControlTemplate all have a Triggers collection, but whereas Style and the template classes accept all three types, FrameworkElement only accepts event triggers.
Fortunately, Style happens to be the logical place to put triggers even if you had a choice because of the ease in sharing them and their direct tie to the visual aspects of elements.

Property trigger
A property trigger activates a list of setters when a property gets a specified value. If the value changes the trigger undoes the setters.

Example #1
    <Grid>
        <Grid.Resources>
            <Style x:Key="styleWithTrigger" TargetType="Rectangle">
                <Setter Property="Fill" Value="LightGreen" />
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Fill" Value="Red" />
                    Trigger>
                Style.Triggers>
            Style>

           
        Grid.Resources>
        <Rectangle Style="{StaticResource styleWithTrigger}">Rectangle>
    Grid>

Example #2
The following update to buttonStyle makes the rotation only happen when the mouse pointer is hovering over the Button (and sets the Foreground to Black rather than White):

 

 <Grid>
        <Grid.Resources>
            <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="RenderTransform">
                            <Setter.Value>
                                <RotateTransform Angle="10"/>
                            Setter.Value>
                        Setter>
                        <Setter Property="Foreground" Value="Black"/>
                    Trigger>
                Style.Triggers>
                <Setter Property="FontSize" Value="22"/>
                <Setter Property="Background" Value="Purple"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="Height" Value="50"/>
                <Setter Property="Width" Value="50"/>
                <Setter Property="RenderTransformOrigin" Value=".5,.5"/>
            Style>


        Grid.Resources>

        <Button Style="{StaticResource buttonStyle}" Width="150" Height="50" Content="OK" />
    Grid>

  
Data Triggers
Data triggers are just like property triggers, except that they can be triggered by any .NET property rather than just dependency properties. (The Setters inside a data trigger are still restricted to setting dependency properties, however.)
To use a data trigger, add a DataTrigger object to the Triggers collection and specify the property/value pair.
To support plain .NET properties, you specify the relevant property with a Binding rather than a simple property name.
Regardless of what element you are binding and the nature of your data source, each binding always follows the model illustrated by the following figure:


The following TextBox has a Style that triggers the setting of IsEnabled based on the value of its Text property, which is not a dependency property. When Text is the string “disabled,” IsEnabled is set to false (which is admittedly an unusual application of a data trigger):



The TextBox Style’s data trigger disables it when its text is “disabled.
<StackPanel Width="200">
        <StackPanel.Resources>
            <Style TargetType="{x:Type TextBox}">
                <Style.Triggers>
                    <DataTrigger
Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}"
Value="disabled">
                        <Setter Property="IsEnabled" Value="False"/>
                    DataTrigger>
                Style.Triggers>
                <Setter Property="Background"
Value="{Binding RelativeSource={RelativeSource Self}, Path=Text}"/>
            Style>
        StackPanel.Resources>
        <TextBox Margin="3"/>
    StackPanel>




Example #2


Here is one example of data trigger. We have a student class and this class contains the student name and grade information.

If we want to change the color of the row if student fail, then we can do it with data trigger. Here is simple XAML code to apply perform this.


namespace WpfApplication23
{
    public partial class MainWindow : Window

    {

         public MainWindow()

         {

             InitializeComponent();
         }

         private void Window_Loaded(object sender, RoutedEventArgs e)

         {

             lstView.Items.Add(new Student("Ahmed", "Fail"));

             lstView.Items.Add(new Student("Ali", "Pass"));

             lstView.Items.Add(new Student("Mohamed", "Pass"));

             lstView.Items.Add(new Student("Omar", "Pass"));

             lstView.Items.Add(new Student("Dina", "Fail"));

             lstView.Items.Add(new Student("Ola", "Pass"));

         }

     }

     public class Student

     {
        public Student(String name, String grade)

         {
             StudentName = name;

             Grade = grade;
         }

       public String StudentName
        { set; get; }
         public String Grade
         { set; get; }
     }
 }

And here's the XAML
    <Window x:Class="WpfApplication23.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

     Title="Data Trigger Demo" Height="300" Width="400" Loaded="Window_Loaded">

        <Window.Resources>

            <Style TargetType="{x:Type ListViewItem}">

                <Style.Triggers>

                    <DataTrigger Binding="{Binding Grade}" Value="Fail">

                        <Setter Property="Background" Value="Red"/>

                        <Setter Property="Foreground" Value="White"/>

                    DataTrigger>

                Style.Triggers>

            Style>

        Window.Resources>

        <Grid>

            <ListView Name="lstView">

                <ListView.View>

                    <GridView>

                        <GridViewColumn Width="180" Header="Student Name" DisplayMemberBinding="{Binding Path = StudentName}">GridViewColumn>

                        <GridViewColumn Width="180" Header="Grade" DisplayMemberBinding="{Binding Path = Grade}">GridViewColumn>

                    GridView>
                ListView.View>
            ListView>
        Grid>
    Window>


Expressing More Complex Logic with Triggers
The logic expressed with the previous triggers has been of the form “when property=value, set the following properties.” But more powerful options exist:
 Multiple triggers can be applied to the same element (to get a logical OR).
Multiple properties can be evaluated for the same trigger (to get a logical AND).

Logical OR
Because Style.Triggers can contain multiple triggers, you can create more than one with the exact same Setters to express a logical OR relationship:

   <Window x:Class="WpfApplication23.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

     Title="Data Trigger Demo" Height="300" Width="400" >

    <Window.Resources>
        <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="RenderTransform">
                        <Setter.Value>
                            <RotateTransform Angle="10"/>
                        Setter.Value>
                    Setter>
                    <Setter Property="Foreground" Value="Black"/>
                Trigger>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="RenderTransform">
                        <Setter.Value>
                            <RotateTransform Angle="10"/>
                        Setter.Value>
                    Setter>
                    <Setter Property="Foreground" Value="Black"/>
                Trigger>
            Style.Triggers>
        Style>
    Window.Resources>
    <Button Content="Button" Height="23" Name="button1" Width="75" Style="{StaticResource buttonStyle}" />
Window>

Logical AND

To express a logical AND relationship, you can use a variation of Trigger called MultiTrigger, or a variation of DataTrigger called MultiDataTrigger. MultiTrigger and MultiDataTrigger have a collection of Conditions that contain the information you would normally put directly inside a Trigger or DataTrigger. Therefore, you can use MultiTrigger as follows:
So we just need to update to the following code
      <Style.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsMouseOver" Value="True"/>
                        <Condition Property="IsFocused" Value="True"/>
                    MultiTrigger.Conditions>
                    <Setter Property="RenderTransform">
                        <Setter.Value>
                            <RotateTransform Angle="10"/>
                        Setter.Value>
                    Setter>
                    <Setter Property="Foreground" Value="Black"/>
                MultiTrigger>
            Style.Triggers>