Get Microsoft Silverlight

Thursday, November 01, 2007

Show all the System.Windows.Media.Colors using DataBinding



Here is a sample to show all the Colors or even Brushes of WPF System.Windows.Media.Colors class.

<ListBox ItemsSource="{Binding Mode=OneWay, Source={StaticResource helper}}"  ItemTemplate="{DynamicResource DataTemplate1}"/>


Bellow is a function which gives all of its properties as PropertyInfo Collection.(If anybody out here knows a way to eliminate the use of this Helper class, please point that here)


public class Helper
{
    public PropertyInfo[] GetPropNames(Type type)
    {
        return type.GetProperties();
    }
}


Now you can write an ObjectDataProvider in XAML to call this function and then a DataTemplate to bind the PropertyName to the approapriate Dependancy Property. See the XAML


  <Window.Resources>
    <ObjectDataProvider x:Key="helper" MethodName="GetPropNames" ObjectType="{x:Type local:Helper}">
      <ObjectDataProvider.MethodParameters>
        <x:Type TypeName="Colors"/>
      </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
 
    <DataTemplate x:Key="DataTemplate1">
      <StackPanel Orientation="Horizontal">
        <Rectangle Width="40" Height="28" Fill="{Binding Name}" Stroke="#FF000000"/>
        <TextBlock  Text ="{Binding Name}" Foreground="{Binding Name}" />
      </StackPanel>
    </DataTemplate>
  </Window.Resources>


Now if you need to show Brushes class members just need to replace Colors from the XAML with Brushes as shown here

    <ObjectDataProvider x:Key="helper" MethodName="GetPropNames" ObjectType="{x:Type local:Helper}">
      <ObjectDataProvider.MethodParameters>
        <x:Type TypeName="Brushes"/>
      </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>

Monday, October 29, 2007

Time Picker User Control

The easiest way to create a WPF TimePicker control is to make a user control wrapped for TimeSpan CLR object. Here is a very simple sample which does that. Basically TimeControl is having 4 DPs one for the entire Value (Which is a TimeSpan) and individual Hours, Minutes and Seconds. (We can optionally add Days and Milliseconds also to make the control rich).

Here is a C# class TimeControl.xaml.cs


    public partial class TimeControl : UserControl
    {
        public TimeControl()
        {
            InitializeComponent();
        }
        public TimeSpan Value
        {
            get { return (TimeSpan)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }
        public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(TimeSpan), typeof(TimeControl),
        new UIPropertyMetadata(DateTime.Now.TimeOfDay, new PropertyChangedCallback(OnValueChanged)));
 
        private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            TimeControl control = obj as TimeControl;
            control.Hours = ((TimeSpan)e.NewValue).Hours;
            control.Minutes = ((TimeSpan)e.NewValue).Minutes;
            control.Seconds = ((TimeSpan)e.NewValue).Seconds;
        }
 
        public int Hours
        {
            get { return (int)GetValue(HoursProperty); }
            set { SetValue(HoursProperty, value); }
        }
        public static readonly DependencyProperty HoursProperty =
        DependencyProperty.Register("Hours", typeof(int), typeof(TimeControl),
        new UIPropertyMetadata(0, new PropertyChangedCallback(OnTimeChanged)));
 
        public int Minutes
        {
            get { return (int)GetValue(MinutesProperty); }
            set { SetValue(MinutesProperty, value); }
        }
        public static readonly DependencyProperty MinutesProperty =
        DependencyProperty.Register("Minutes", typeof(int), typeof(TimeControl),
        new UIPropertyMetadata(0, new PropertyChangedCallback(OnTimeChanged)));
 
        public int Seconds
        {
            get { return (int)GetValue(SecondsProperty); }
            set { SetValue(SecondsProperty, value); }
        }
 
        public static readonly DependencyProperty SecondsProperty =
        DependencyProperty.Register("Seconds", typeof(int), typeof(TimeControl),
        new UIPropertyMetadata(0, new PropertyChangedCallback(OnTimeChanged)));
 
 
        private static void OnTimeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            TimeControl control = obj as TimeControl;
            control.Value = new TimeSpan(control.Hours, control.Minutes, control.Seconds);
        }
 
        private void Down(object sender, KeyEventArgs args)
        {
            switch (((Grid)sender).Name)
            {
                case "sec":
                    if (args.Key == Key.Up)
                        this.Seconds++;
                    if (args.Key == Key.Down)
                        this.Seconds--;
                    break;
 
                case "min":
                    if (args.Key == Key.Up)
                        this.Minutes++;
                    if (args.Key == Key.Down)
                        this.Minutes--;
                    break;
 
                case "hour":
                    if (args.Key == Key.Up)
                        this.Hours++;
                    if (args.Key == Key.Down)
                        this.Hours--;
                    break;
            }
        }
 
    } 



And here is the XAML for TimeControl.xaml





<UserControl

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

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

    x:Class="DateTimeTest.TimeControl"

    Height="Auto" Width="Auto" x:Name="UserControl">

  <Grid x:Name="LayoutRoot" Width="Auto" Height="Auto">

    <Grid.ColumnDefinitions>

      <ColumnDefinition Width="0.2*"/>

      <ColumnDefinition Width="0.05*"/>

      <ColumnDefinition Width="0.2*"/>

      <ColumnDefinition Width="0.05*"/>

      <ColumnDefinition Width="0.2*"/>

    </Grid.ColumnDefinitions>

    <Grid x:Name="hour" Focusable="True" KeyDown="Down">

      <TextBlock x:Name="mmTxt" TextWrapping="Wrap" Text="{Binding Path=Hours, ElementName=UserControl, Mode=Default}"

                 TextAlignment="Center" VerticalAlignment="Center" FontFamily="Goudy Stout" FontSize="14"/>

    </Grid>

    <Grid  Grid.Column="1">

      <TextBlock  x:Name="sep1" TextWrapping="Wrap" VerticalAlignment="Center" Background="{x:Null}" FontFamily="Goudy Stout"

                  FontSize="14" Text=":" TextAlignment="Center"/>

    </Grid>

    <Grid  Grid.Column="2" x:Name="min" Focusable="True" KeyDown="Down">

      <TextBlock  x:Name="ddTxt"  TextWrapping="Wrap" Text="{Binding Path=Minutes, ElementName=UserControl, Mode=Default}"

                  TextAlignment="Center" VerticalAlignment="Center" FontFamily="Goudy Stout" FontSize="14"/>

    </Grid>

    <Grid  Grid.Column="3">

      <TextBlock x:Name="sep2"  TextWrapping="Wrap" VerticalAlignment="Center" Background="{x:Null}" FontFamily="Goudy Stout"

                 FontSize="14" Text=":" TextAlignment="Center"/>

    </Grid>

    <Grid  Grid.Column="4" Name="sec" Focusable="True" KeyDown="Down">

      <TextBlock x:Name="yyTxt"  TextWrapping="Wrap" Text="{Binding Path=Seconds, ElementName=UserControl, Mode=Default}"

                 TextAlignment="Center" VerticalAlignment="Center" FontFamily="Goudy Stout" FontSize="14"/>

    </Grid>

 

  </Grid>

</UserControl>


And the control can be used as

<ctrl:TimeControl Hours="10" Minutes="10" Seconds="30" x:Name="TimeControl"/>

Thursday, October 04, 2007

Blendables essentials mix v1.0 now available

A bunch of controls and utilities for Windows Presentation Foundation(WPF) has been released by Identitymine. You can take a look at Blendables here . And there is a WPF programming contest is also going on there.

Have you ever wished to have a Carousal3D in your WPF app? or a ready to use Zoombox or a TimelinePanel.
And have you ever thought of doing more things inside the XAML itself with out doing much C# coding? then you really need this exciting utility comming along with Blendables called EvalBinding and Simple Binding.

Cheers!!!

Wednesday, March 14, 2007

Simple WPF Clock using Microsoft Expression Blend











Today I spend some time playing with Microsoft Expression Blend. and thought of creating a XAML Clock using Blend itself. Surprisingly it took less than 2 hours for me to create a good looking Clock. Here is the preview of my XAML Clock.

Below are the simple design steps I followed.
1) Created a Class TimeAngles which stores Angles corresponds to Hour,Minute and second.

2) Created an IValueConverter class for converting the DateTime.Now to Angles.

3) Bounded the each Angle properties of TimeAngles class to the Rotation RenderTransform of each Clock Hand (Which are Rectangle in my code)

4) Updated the DataContext of Clock in each second through a Despatcher Timer.


Here is a screen shot of the project opened up my Blend. I have used BitMapEffect extensively to achieve this kind of a UI.

Source code is Available here

Tuesday, January 09, 2007

Compare Objects in XAML using a generic IValueConverter

Here is a way for XAM Designers to compare two instances inside XAML using an IValueConverter. Imagine that you have a ComboBox and few other controls. ComboBox is bounded to a Collection of objects (In my attached code I am binding it to an Enum). In such a situation the UI designer wants to enable/disable some other controls based on the selected value of the ComboBox. He can use the following IValueConnverter class as a Generic comparer which will return a true or false.

public class GenericComparer : IValueConverter
{
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return false;

// If the object has implemented IComparable
if (value is IComparable)
{
if (((IComparable)value).CompareTo(parameter) == 0)
return true;
}
else if (value.Equals(parameter))
return true;


return false;
}

Now instantiate a comparer in the resource as follows.

………………


If we wanted to control the IsEnabled property of a text box the XAML will be like


See the attached source code for details.