Sony Arouje

a programmer's log

Archive for August 2010

Callouts in Silverlight

with 4 comments

As per the project requirement I have to show some Callouts. I was thinking of creating it using paths and curves. It would have been a lot of work. But blend saved my time. Blend provides callouts and other shapes in toolbar, VS editor wont provide it in toolbar. Below xaml shows a callout with an Oval textbox (Oval textbox I mentioned in my earlier post).

Name Space: System.Windows.Shapes

XAML

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
    xmlns:we="clr-namespace:Designer.Controls"
    mc:Ignorable="d"
    x:Class="Designer.Controls.CallOutOval"
    d:DesignWidth="640" d:DesignHeight="480">

    <Grid x:Name="LayoutRoot">
        <ed:Callout AnchorPoint="0,1.25" CalloutStyle="Oval" Fill="#FFF4F4F5" FontSize="14.666999816894531" Stroke="Black" HorizontalAlignment="Left" VerticalAlignment="Top">
            <ContentControl>
                <we:OvalTextBox Text="Your Text here" CornerRadius="50" BorderThickness="0" Background="Transparent"></we:OvalTextBox>
            </ContentControl>
        </ed:Callout>
    </Grid>
</UserControl>

Blend provides different callouts like Oval, Rectangle and Cloud. We are done with the Callout user control.

Written by Sony Arouje

August 30, 2010 at 5:38 pm

Image dragging and dropping in Silverlight

leave a comment »

In this sample code I am going to demonstrate how we can drag and drop an image from windows explorer to a Silverlight page.

To run the test we should have a page with an Image control. Lets call our Image control as ImgShow. In the xaml, set the AllowDrop property to true. Also add a drop event to the Image control. Once the drop event is added go to the code behind and add the below code to the event.

private void ImgShow_Drop(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
    {
        FileInfo[] fi = (FileInfo[])e.Data.GetData(DataFormats.FileDrop);
        BitmapImage img = new BitmapImage();
        using (Stream fileStream = fi[0].OpenRead())
        {
            img.SetSource(fileStream);
        }
        ImgShow.Source = img;
    }
}

We are done with the application. Run the application and drag and drop a file from Windows explorer to ImgShow image control.

Written by Sony Arouje

August 25, 2010 at 4:26 pm

Posted in Silverlight

Silverlight Toolbar control

with 7 comments

In this post I am explaining how to create a basic toolbar in Silverlight. This toolbar has two parts

    • Toolbar panel
    • Toolbar item

Screen shot

image

ToolBar Panel

This user control holds all the Toolbar items. This control internally uses Stackpanel to organize the Toolbar items. Below is the XAML and code behind

XAML

<UserControl x:Class="Controls.ToolBarPanel"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
             Background="Transparent"
    d:DesignHeight="300" d:DesignWidth="400">
    
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <StackPanel x:Name="itemHolder" Orientation="{Binding Orientation}" Background="Transparent"></StackPanel>
    </Grid>
</UserControl>

Code behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Controls
{
    public partial class ToolBarPanel : UserControl
    {
        public event Click ToolBarItemClick;
        public ToolBarPanel()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(ToolBarPanel_Loaded);
        }

        void ToolBarPanel_Loaded(object sender, RoutedEventArgs e)
        {
            this.CreateClickEvent();
        }

        public static DependencyProperty ToolBarItemsProperty = DependencyProperty.Register("ToolBarItems",
        typeof(PresentationFrameworkCollection<ToolBarItem>),
        typeof(ToolBarPanel),
        new PropertyMetadata(null));
        public UIElementCollection ToolBarItems
        {
            get 
            {
                return itemHolder.Children;
            }
        }

        public static DependencyProperty ToolBarItemsOrientation = DependencyProperty.Register("Orientation",
        typeof(Orientation),
        typeof(ToolBarPanel),
        new PropertyMetadata(null));
        public Orientation Orientation
        {
            get { return (itemHolder.Orientation); }
            set { itemHolder.Orientation=value; }
        }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            itemHolder.DataContext = this;
        }

        private void CreateClickEvent()
        {
            foreach (UIElement elem in itemHolder.Children)
            {
                ToolBarItem item = elem as ToolBarItem;
                if(item!=null)
                    item.ToolBarItemClick += new Click(item_ToolBarItemClick);
            }
        }

        void item_ToolBarItemClick(object sender, string key)
        {
            if (ToolBarItemClick != null)
                this.ToolBarItemClick(sender, ((ToolBarItem)sender).ToolBarItemKey);
        }

    }
}

 

One property I wanted to highlight here is the ToolbarItems dependency property. This property exposes the StackPanels children property. Users can add Toolbar items through this property. At the end of this post, with a sample code I will explain the properties.

The delegate Click used in the ToolbarPanel is declared in ToolBarItem code.

ToolBar Item

This control creates the Toolbar button, it inherits from Button control. To make it similar to toolbar button I modified the Resource template of the button. Apart from the default properties of button a new property is added to provide the ability to add Image.

XAML

<Button x:Class="Controls.ToolBarItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <Button.Resources>
        <ControlTemplate x:Key="BtnToolBarItemStyle" TargetType="Button">
            <Grid>
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Disabled"/>
                        <VisualState x:Name="Normal"/>
                        <VisualState x:Name="MouseOver">
                            <Storyboard>
                                <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="border" d:IsOptimized="True"/>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="border">
                                    <DiscreteObjectKeyFrame KeyTime="0">
                                        <DiscreteObjectKeyFrame.Value>
                                            <Thickness>0</Thickness>
                                        </DiscreteObjectKeyFrame.Value>
                                    </DiscreteObjectKeyFrame>
                                </ObjectAnimationUsingKeyFrames>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="border">
                                    <DiscreteObjectKeyFrame KeyTime="0">
                                        <DiscreteObjectKeyFrame.Value>
                                            <Thickness>1</Thickness>
                                        </DiscreteObjectKeyFrame.Value>
                                    </DiscreteObjectKeyFrame>
                                </ObjectAnimationUsingKeyFrames>
                                <ColorAnimation Duration="0" To="#FFF9B167" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="border" d:IsOptimized="True"/>
                                <ColorAnimation Duration="0" To="#FFFFEFB6" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="border" d:IsOptimized="True"/>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.CornerRadius)" Storyboard.TargetName="border">
                                    <DiscreteObjectKeyFrame KeyTime="0">
                                        <DiscreteObjectKeyFrame.Value>
                                            <CornerRadius>4</CornerRadius>
                                        </DiscreteObjectKeyFrame.Value>
                                    </DiscreteObjectKeyFrame>
                                </ObjectAnimationUsingKeyFrames>
                                <ColorAnimation Duration="0" To="#FFDEA158" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="border" d:IsOptimized="True"/>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Pressed"/>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <Border x:Name="border" BorderBrush="Black" BorderThickness="1" Margin="1,2,2,1" Opacity="0">
                    <Border.Background>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="Black" Offset="0"/>
                            <GradientStop Color="White" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.Background>
                </Border>
                <StackPanel Orientation="Horizontal">
                    <Border x:Name="imgBorder"  BorderBrush="Black" BorderThickness="0" Margin="0" Width="16" Height="16">
                        <Border.Background>
                            <ImageBrush x:Name="imgBorderBrush" Stretch="Fill" ImageSource="{Binding ToolBarItemImage}"/>
                        </Border.Background>
                    </Border>
                    <TextBlock x:Name="caption" Grid.Column="1" TextWrapping="NoWrap" Text="{Binding Content}" FontSize="9.333" TextAlignment="Center" VerticalAlignment="Center" />
                </StackPanel>
            </Grid>
        </ControlTemplate>
    </Button.Resources>

    <Button.Template>
        <StaticResource ResourceKey="BtnToolBarItemStyle"/>
    </Button.Template>
    
</Button>

 

Code Behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections;
using System.ComponentModel;
namespace Controls
{
    public delegate void Click(object sender, string key);
    public partial class ToolBarItem : Button
    {
        public event Click ToolBarItemClick;
        public ToolBarItem()
        {
            InitializeComponent();
            this.Click += new RoutedEventHandler(ToolBarItem_Click);
        }

        void ToolBarItem_Click(object sender, RoutedEventArgs e)
        {
            if (ToolBarItemClick != null)
                this.ToolBarItemClick(sender, (string)GetValue(ToolBarItemKeyProperty));
        }

        public static DependencyProperty ToolBarItemImageProperty = DependencyProperty.Register("ToolBarItemImage",
        typeof(ImageSource),
        typeof(ToolBarItem),
        new PropertyMetadata(null));
        public ImageSource ToolBarItemImage
        {
            get { return (ImageSource)GetValue(ToolBarItemImageProperty); }
            set { SetValue(ToolBarItemImageProperty, value); }
        }

        public static DependencyProperty ToolBarItemKeyProperty = DependencyProperty.Register("ToolBarItemKey",
        typeof(String),
        typeof(ToolBarItem),
        new PropertyMetadata(null));
        public string ToolBarItemKey
        {
            get { return (string)GetValue(ToolBarItemKeyProperty); }
            set { SetValue(ToolBarItemKeyProperty, value); }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            SetDataContext();
        }
        private void SetDataContext()
        {
            Border border = GetTemplateChild("imgBorder") as Border;
            border.DataContext = this;
            TextBlock txtCaption = GetTemplateChild("caption") as TextBlock;
            txtCaption.DataContext = this;

            if (this.Content == null)
            {
                txtCaption.Margin = new Thickness(0);
                border.Margin = new Thickness(3);
            }
            else
            {
                txtCaption.Margin = new Thickness(3);
            }
        }

    }
}
  • ToolBarItemImage: To set the source of the Image to display in the toolbar.

  • ToolBarItemKey: Provide a key to identify which button is clicked.

Test Page

The test page helps you to understand how we can use this new control

XAML

<controls:ChildWindow x:Class="Popups.TestToolBar"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
           xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
           xmlns:tlBar="clr-namespace:EmblemDesigner.Controls" Title="TestToolBar" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="265" d:DesignWidth="432">
    <Grid x:Name="LayoutRoot" Margin="2">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        
        <tlBar:ToolBarPanel Height="50" Background="Transparent" Orientation="Horizontal" ToolBarItemClick="ToolBarPanelExt_ToolBarItemClick" >
            <tlBar:ToolBarPanel.ToolBarItems>
                <tlBar:ToolBarItem Margin="5" ToolBarItemImage="/Ico_Arrow.png"  Content="Arrow" ToolBarItemKey="Arrow"></tlBar:ToolBarItem>
                <tlBar:ToolBarItem Margin="5" ToolBarItemImage="/Ico_Circle.png"   ToolBarItemKey="Circle"></tlBar:ToolBarItem>
            </tlBar:ToolBarPanel.ToolBarItems>
        </tlBar:ToolBarPanel>
        
        <Button x:Name="CancelButton"  Content="Cancel" Click="CancelButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
        <Button x:Name="OKButton"  Content="OK" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" />
    </Grid>
</controls:ChildWindow>

 

Code Behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Popups
{
    public partial class TestToolBar : ChildWindow
    {
        public TestToolBar()
        {
            InitializeComponent();
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }


        private void ToolBarPanel_ToolBarItemClick(object sender, string key)
        {
            switch (key)
            {
                case "circle":
                    break;
                case "arrow":
                    break;
            }
        }
    }
}
 

If we attach ToolBarItemClick event to ToolBar panel, it will generate an even handler as shown above in italics. The event will provide you a key and the sender. The key provides the value we set for ToolBarItemKey of the ToolBarItem control. Based on the key we can take different actions. As ToolbarItem is inherited from button you can use the default click event provided by Button control.

Written by Sony Arouje

August 25, 2010 at 4:26 pm

Posted in Silverlight

Tagged with ,

Oval TextBox

leave a comment »

My project require an oval text box. First place I started to make my changes is in the default template of Textbox. The default template of any control can be retrieved through expression blend (Right click on the Control and select Edit Template/Edit a Copy).

Below is the default template of TextBox control

    <UserControl.Resources>
        <ControlTemplate x:Key="ValidationToolTipTemplate">
            <Grid x:Name="Root" Margin="5,0" Opacity="0" RenderTransformOrigin="0,0">
                <Grid.RenderTransform>
                    <TranslateTransform x:Name="xform" X="-25"/>
                </Grid.RenderTransform>
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="OpenStates">
                        <VisualStateGroup.Transitions>
                            <VisualTransition GeneratedDuration="0"/>
                            <VisualTransition GeneratedDuration="0:0:0.2" To="Open">
                                <Storyboard>
                                    <DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="X" Storyboard.TargetName="xform">
                                        <DoubleAnimation.EasingFunction>
                                            <BackEase Amplitude=".3" EasingMode="EaseOut"/>
                                        </DoubleAnimation.EasingFunction>
                                    </DoubleAnimation>
                                    <DoubleAnimation Duration="0:0:0.2" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
                                </Storyboard>
                            </VisualTransition>
                        </VisualStateGroup.Transitions>
                        <VisualState x:Name="Closed">
                            <Storyboard>
                                <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Open">
                            <Storyboard>
                                <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="X" Storyboard.TargetName="xform"/>
                                <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <Border Background="#052A2E31" CornerRadius="5" Margin="4,4,-4,-4"/>
                <Border Background="#152A2E31" CornerRadius="4" Margin="3,3,-3,-3"/>
                <Border Background="#252A2E31" CornerRadius="3" Margin="2,2,-2,-2"/>
                <Border Background="#352A2E31" CornerRadius="2" Margin="1,1,-1,-1"/>
                <Border Background="#FFDC000C" CornerRadius="2"/>
                <Border CornerRadius="2">
                    <TextBlock Foreground="White" MaxWidth="250" Margin="8,4,8,4" TextWrapping="Wrap" Text="{Binding (Validation.Errors)[0].ErrorContent}" UseLayoutRounding="false"/>
                </Border>
            </Grid>
        </ControlTemplate>
        <Style x:Key="OvalTextBoxStyle" TargetType="TextBox">
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Background" Value="#FFFFFFFF"/>
            <Setter Property="Foreground" Value="#FF000000"/>
            <Setter Property="Padding" Value="2"/>
            <Setter Property="BorderBrush">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFA3AEB9" Offset="0"/>
                        <GradientStop Color="#FF8399A9" Offset="0.375"/>
                        <GradientStop Color="#FF718597" Offset="0.375"/>
                        <GradientStop Color="#FF617584" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TextBox">
                        <Grid x:Name="RootElement">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <ColorAnimation Duration="0" To="#FF99C1E2" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="MouseOverBorder"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="ReadOnly">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ReadOnlyVisualElement"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates">
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unfocused">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="ValidationStates">
                                    <VisualState x:Name="Valid"/>
                                    <VisualState x:Name="InvalidUnfocused">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="InvalidFocused">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" Storyboard.TargetName="validationTooltip">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <System:Boolean>True</System:Boolean>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"  Opacity="1" CornerRadius="20">
                                <Grid>
                                    <Border x:Name="ReadOnlyVisualElement" Background="#5EC9C9C9" Opacity="0" CornerRadius="20"/>
                                    <Border x:Name="MouseOverBorder" BorderBrush="Transparent" BorderThickness="1" CornerRadius="20">
                                        <ScrollViewer x:Name="ContentElement" BorderThickness="0" IsTabStop="False" Padding="{TemplateBinding Padding}"/>
                                    </Border>
                                </Grid>
                            </Border>
                            <Border x:Name="DisabledVisualElement" BorderBrush="#A5F7F7F7" BorderThickness="{TemplateBinding BorderThickness}" Background="#A5F7F7F7" IsHitTestVisible="False" Opacity="0" CornerRadius="20"/>
                            <Border x:Name="FocusVisualElement" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}" IsHitTestVisible="False" Margin="1" Opacity="0" CornerRadius="20"/>
                            <Border x:Name="ValidationErrorElement" BorderBrush="#FFDB000C" BorderThickness="1"  Visibility="Collapsed" CornerRadius="20">
                                <ToolTipService.ToolTip>
                                    <ToolTip x:Name="validationTooltip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource ValidationToolTipTemplate}">
                                        <ToolTip.Triggers>
                                            <EventTrigger RoutedEvent="Canvas.Loaded">
                                                <BeginStoryboard>
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="validationTooltip">
                                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                                <DiscreteObjectKeyFrame.Value>
                                                                    <System:Boolean>true</System:Boolean>
                                                                </DiscreteObjectKeyFrame.Value>
                                                            </DiscreteObjectKeyFrame>
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </BeginStoryboard>
                                            </EventTrigger>
                                        </ToolTip.Triggers>
                                    </ToolTip>
                                </ToolTipService.ToolTip>
                                <Grid Background="Transparent" HorizontalAlignment="Right" Height="12" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12">
                                    <Path Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C" Margin="1,3,0,0"/>
                                    <Path Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff" Margin="1,3,0,0"/>
                                </Grid>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

To make my TextBox oval I wanted to add/edit the CornerRadius property to some of the Border controls in the above Template. Below are the Borders we need to visit.

Border
DisabledVisualElement
FocusVisualElement
ReadOnlyVisualElement
MouseOverBorder

Add/Modify CornerRadius property to the above Borders and set it to what ever the value you need.

But the hurdle here is to change the CornerRadius, every time we need to set a different value to all the Border control I mentioned above. To make my life easier I created a new TextBox user control with CornerRadius property.

 TextBox with CornerRadius property

Create a new UserControl and inherit from TextBox as shown below

<TextBox x:Class=”SonyControls.Controls.OvalTextBox”
  
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;
  
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;
  
xmlns:d=”http://schemas.microsoft.com/expression/blend/2008&#8243;
  
xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;
  
xmlns:System=”clr-namespace:System;assembly=mscorlib”
  
mc:Ignorable=”d”
  
d:DesignHeight=”300″d:DesignWidth=”400″>

    <TextBox.Resources>
                 I am not adding the entire template here. Its already depicted above.

….

…..

….

         <Border x:Name=”Border” BorderBrush=”{TemplateBinding BorderBrush}” BorderThickness=”{TemplateBinding BorderThickness}”

         Background=”{TemplateBinding Background}” Opacity=”1″ CornerRadius={Binding CornerRadius}>

      </TextBox.Resources>

               <TextBox.Style>

                         <StaticResource ResourceKey=”OvalTextBoxStyle”/>

             </TextBox.Style

</TextBox>

Modify the CornerRadius value with “{Binding CornerRadius}” as shown above.

In the code behind of my user control I added a dependency property and some code as shown below.

public partial class OvalTextBox : TextBox { public OvalTextBox() { InitializeComponent(); } public static DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(OvalTextBox), new PropertyMetadata(null)); public CornerRadius CornerRadius { get { return (CornerRadius)GetValue(CornerRadiusProperty); } set { SetValue(CornerRadiusProperty, value); } } public override void OnApplyTemplate() { base.OnApplyTemplate(); SetDataContext();

    }

private void SetDataContext()

{

string[] bordersToUpdate = { "Border", "DisabledVisualElement", "FocusVisualElement","ReadOnlyVisualElement", "MouseOverBorder", "WatermarkVisualElement" };

foreach (string str in bordersToUpdate)

{

Border border = GetTemplateChild(str) as Border;

if (border != null)

{ border.DataContext = this; }

}

}

}

 

That’s it we are done with a new Textbox with CornerRadius property, you can access the new property from Code behind or through XAML.

Written by Sony Arouje

August 25, 2010 at 4:25 pm

Posted in Silverlight

Silverlight UserControl Inheritance

leave a comment »

My current project requires several silverlight user controls. Most of the control has some common functionalities. I decided to create a base class inherits from UserControl. Then add the base class to my user controls.

The issue arise when I tried to build the solution, I started getting the bellow compile time error.

Error    1    Partial declarations of ‘ImageEditor.Controls.CallOut’ must not specify different base classes    F:\XXXX\obj\Debug\Controls\CallOut.g.i.cs    36    26    <ProjectName>

The solution to this issue is, in XAML change <UserControl …..</UserControl> to the name of your base class. See the eg. below

<UI:ControlBase x:Class="ImageEditor.Controls.CallOut"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:UI="clr-namespace:ImageEditor.Controls"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">    
    <Grid x:Name="LayoutRoot" Background="White">
        <Border  x:Name="rectBorder" Grid.Row="0" BorderBrush="Black" BorderThickness="3" CornerRadius="5">
            <TextBox x:Name="txtAnnotate" AcceptsReturn="True"></TextBox>
        </Border>
    </Grid>
</UI:ControlBase >

In the above xaml I replace UserControl with my base class. In order to use my base class I should refer my namespace using xmlns:UI=”clr-…..”. You can see the changes by looking at the sections underlined.

Written by Sony Arouje

August 25, 2010 at 4:24 pm

Posted in Silverlight

Image Positioning in Silverlight

leave a comment »

The below code will give you a basic idea of how dragging and positioning an image inside a Canvas will work.

XAML code

<UserControl x:Class=”EmblemDesigner.MainPage”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
    xmlns:d=”http://schemas.microsoft.com/expression/blend/2008″
    xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006″
    mc:Ignorable=”d”
    d:DesignHeight=”300″ d:DesignWidth=”400″>

    <Grid x:Name=”LayoutRoot” Background=”White”>
        <Canvas x:Name=”emblemDesign” AllowDrop=”True” Background=”Black” MouseLeftButtonUp=”emblemDesign_MouseLeftButtonUp” MouseMove=”imgEmblem_MouseMove”>
                          <Image x:Name=”imgEmblem” Source=”/Images/One.jpg” Height=”100″ Width=”100″ MouseLeftButtonDown=”imgEmblem_MouseLeftButtonDown”  MouseLeftButtonUp=”imgEmblem_MouseLeftButtonUp”></Image>
           
        </Canvas>
    </Grid>
</UserControl>

 

Code Behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace EmblemDesigner
{
    public partial class MainPage : UserControl
    {
        double _imgPosX = 0;
        double _imgPosY = 0;
        double _mousePosX = 0;
        double _mousePosY = 0;
        bool _isLeftMouseDown = false;

        public MainPage()
        {
            InitializeComponent();
         }

        private void imgEmblem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            _isLeftMouseDown = true;
            _imgPosX = imgEmblem.Margin.Top;
            _imgPosY = imgEmblem.Margin.Left;

            _mousePosX = e.GetPosition(imgEmblem).X;
            _mousePosY = e.GetPosition(imgEmblem).Y;

            imgEmblem.Cursor = Cursors.Hand;
        }

        private void imgEmblem_MouseMove(object sender, MouseEventArgs e)
        {
             if (_isLeftMouseDown == false)
                return;

              TranslateTransform tt = new TranslateTransform();

           
            if (_imgPosX != -1)
            {
                tt.X = _imgPosX + (e.GetPosition(emblemDesign).X – _mousePosX);
            }
            if (_imgPosY != -1)
            {
                tt.Y = _imgPosY + (e.GetPosition(emblemDesign).Y – _mousePosY);
            }
            imgEmblem.RenderTransform = tt;
            resizeCanvas.Margin = imgEmblem.Margin;
            System.Diagnostics.Debug.WriteLine(“X={0} y={1}”, tt.X, tt.Y);           
        }

        private void imgEmblem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _isLeftMouseDown = false;
            imgEmblem.Cursor = Cursors.Arrow;
        }

        private void emblemDesign_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            //_isLeftMouseDown = false;
        }

    }
}

Written by Sony Arouje

August 25, 2010 at 4:22 pm

Posted in Silverlight

Silverlight Developer runtime not installed Error

leave a comment »

I started getting the error “Unable to start debugging. The Silverlight Developer Runtime is not installed. Please install a matching version.”. The error started poping  after I installed Silverlight 4.0 tools. The resolution to this problem is to install Silverlight_Developer.exe. You can download the setup from http://go.microsoft.com/fwlink/?LinkID=188039 .

Thanks to the post http://forums.silverlight.net/forums/p/176999/421658.aspx

Written by Sony Arouje

August 25, 2010 at 4:20 pm

Posted in Silverlight

Generic Factory

leave a comment »

Here I am explaining how we can create a Factory class that is similar to ChannelFactory class. Who ever worked on Windows communication foundation will be aware of how to create a channel to a service using ChannelFactory. Creating a channel to the service is as follows.
ChannelFactory<> factory=new ChannelFactory<>
Unfortunately I couldn’t find any class that can create an object like ChannelFactory. So I created a Factory class that will create the object by just passing the interface.

I created a xml file to configure the interface and the class implements it. Below is the structure of my xml file.

<Configurations>
    <Config Interface=”IAddressBo” ActivatorClass=”AddressBo.CAddress” FullPath=”AddressBo.dll”></Config>
    <Config Interface=”IUserBo” ActivatorClass=”UserManager.UserBo” FullPath=”UserManager.dll”></Config>
</Configurations>

Below is the class reads the xml and create the instance of the requested class

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Configuration;
using System.Xml.Linq;
using System.Threading;
namespace Factory
{
    public class ObjectFactory
    {
        public static I CreateInstance<I>() where I : class
        {
                if (_pooledObjects.ContainsKey(typeof(I)) == false)
                {
                    object classInstance = InstanceCreator<I>();
                    _pooledObjects.Add(typeof(I), classInstance);
                }
                return _pooledObjects[typeof(I)] as I;
        }

        private static object InstanceCreator<I>() where I:class
        {
            string className = null;
            string fullPath = null;

            XDocument configXML = XDocument.Load(“BoConfig.xml”);
            var configs = (from config in configXML.Descendants(“Config”)
                          where (config.Attribute(“Interface”).Value == typeof(I).Name.ToString())
                          select new AssemblyDetails
                          {
                              ActivatorClass = config.Attribute(“ActivatorClass”).Value,
                              FullPath = config.Attribute(“FullPath”).Value
                          }).Take(1);

            AssemblyDetails assemblyDetail = configs.First<AssemblyDetails>();
            className = assemblyDetail.ActivatorClass;
            fullPath = assemblyDetail.FullPath;

            if (className != null)
            {
                Assembly assembly;
                assembly = Assembly.LoadFrom(fullPath);
                Type type = assembly.GetType(className);
                return Activator.CreateInstance(type);
            }
            else
            {
                return null;
            }
        }
    }
}

AssemblyDetails  is a class created to store the details of the assembly. Below is the class

public class AssemblyDetails
{
    string _activatorClass;
    string _fullPath;
    public string ActivatorClass
    {
        get { return _activatorClass; }
        set { _activatorClass = value; }
    }
    public string FullPath
    {
        get { return _fullPath; }
        set { _fullPath = value; }
    }
}

Now it’s the time to see how can we create an instance of a class.

IUserBo user = ObjectFactory.CreateInstance<IUserBo>();

Technorati Tags: ,

Written by Sony Arouje

August 25, 2010 at 4:19 pm

Posted in .NET

Tagged with

WCF Hosting an easy method

with 2 comments

My current project is based on WCF service. One of my responsibility is to find a method to host the WCF service. I googled a lot and failed to find one. Every site mentioned about creating ServiceHost instance one by one and call the open method on all service. The disadvantage of this method is we need to add a ServiceHost instance when ever we add a new service to the hosting application. Thus by modifying the service host application

So I come across with an idea of a method to read the Service configuration and host each service. Following is the method I created.

using System.Xml.Linq;

private static List<Type> ServiceHostHelper()
{
    XDocument configXML = XDocument.Load(“ServiceHost.exe.config“); //load the app config file to read using LINQ.
    var configs = (from config in configXML.Descendants(“service”)
                       select new AssemblyDetails
                       {
                           ActivatorClass = config.Attribute(“name”).Value
                       }
                   );

    Assembly assembly;
    assembly = Assembly.LoadFrom(“AddressMngr.dll”);
    List<Type> assmTypes = new List<Type>();
    foreach (AssemblyDetails assm in configs)
    {

//reflection to get the type of the service.         
        Type type = assembly.GetType(assm.ActivatorClass);         assmTypes.Add(type);
    }
    return assmTypes;
}

AssemblyDetails is my class to store the name of the service class. Below is the class

public class AssemblyDetails
{
    string _activatorClass;
    string _fullPath;
    public string ActivatorClass
    {
        get { return _activatorClass; }
        set { _activatorClass = value; }
    }
    public string FullPath
    {
        get { return _fullPath; }
        set { _fullPath = value; }
    }
}

Now lets see how I host the service. Here I host service using a console application

static void Main(string[] args)
{
    List<Type> services = ServiceHostHelper(); // services object will have all the services we defined in the app.config

    ServiceHost[] hostApp = new ServiceHost[services.Count];
    Console.WriteLine(“Following Services are Started”);
    for (int i=0;i<services.Count;i++)
    {

            Type service = services[i];
            hostApp[i] = new ServiceHost(service);
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(service.ToString());

            hostApp[i].Open();
    }
    Console.ForegroundColor = ConsoleColor.Gray;
    string key=string.Empty ;
    do
    {
        Console.Write(“Type exit to terminate the host>”);
        key = Console.ReadLine();
        if (key == “exit”)
        {
            for (int i = 0; i < services.Count; i++)
            {
                hostApp[i].Close();
            }
        }
    } while (key != “exit”);
}

We also need to see how I configured the service. Here is my app.config configuration

<services>
  <service name=”AddressMngr.UserManager“>
    <endpoint address=”net.tcp://localhost:8001/UserManager”
              binding=”netTcpBinding”
              bindingConfiguration=”TransactionalTCP”
              contract=”AddressMngr.IUser”/>
  </service>
  <service name=”AddressMngr.Address” behaviorConfiguration=”ThrottledBehaviour”>
    <endpoint address=”net.tcp://localhost:8001/Address”
      binding=”netTcpBinding”
      bindingConfiguration=”TransactionalTCP”
      contract=”AddressMngr.IAddress”/>
  </service>
</services>

One thing we need to take care is the service name (marked in red) should be same as the class we implemented the Service contract with full name space. I am giving the fully qualified name is to load the class using reflection.

If you have any question then let me know, am happy to help you.

Technorati Tags: ,

Written by Sony Arouje

August 25, 2010 at 4:17 pm

Posted in WCF

Tagged with ,

%d bloggers like this: