Design .Net

Designers, Controls And everything between them.
Debugging Windows Service StartUp

Lately I have been trying to find a good and simple way to debug a Windows Service Project most ways I came a cross on the web have suggested Starting your widows service with a sleep timer which will allow enough time to attache a debugger to to your service. The other common way of doing this is to initiate a debugger launch each time the service Startup and to control the debugger launching in a configurable manageable way. I found this to approaches rather complicated.

In this post I will suggest an alternate method of debugging a service at startup.  

Step 1: Create a windows service project :

windbg1

Step 2: Create two new services, one will be your main service which will perform all of your service logic, the other one will be you debug service. The debug service will help us debug the main service OnStart. This will looks a little something like this:

debug01

Please note that in order to identify both Services in Services window we need to specify their names:

Debug service:

   29         private void InitializeComponent()

   30         {

   31             //

   32             // Service2

   33             //

   34             this.ServiceName = "DebugService";

   35 

   36         }

 
Main service:

   29         private void InitializeComponent()

   30         {

   31             //

   32             // Service1

   33             //

   34             this.ServiceName = "MainService";

   35 

   36         }

Step 3: Add an Installer to your solution and place both of your services in the designer:

debug02

Make sure you have named your services in the installer, I prefer naming them with the same prefix this way both of the services will be displayed together in the services list.

   34             // ServiceName must equal those on ServiceBase derived classes.           

   35             serviceInstaller1.ServiceName = "MainService";

   36             serviceInstaller2.ServiceName = "MainDebugService";

Step 4: In you program.cs make sure that both services are added to the ServicesToRun:

   16             ServiceBase[] ServicesToRun;

   17             ServicesToRun = new ServiceBase[]

   18             {

   19                 new MainService(),new DebugService()

   20             };

   21             ServiceBase.Run(ServicesToRun);

Step 5: Install your service, in the command prompt type "installutil.exe <YourService.exe>". You can view the services list and check that you services are added successfully.

debug03

Now all you have to do if you wish to debug your OnStart method is to Start your DebugService, then attach a debugger to the process.exe, place a break point at the OnStart and finally start your MainService.

 

*Njoy

Posted: Aug 26 2008, 02:36 PM by Yogev | with 4 comment(s)
תגים:,
SliverLight2 Beta Quick Tip Panning: Implement MultiScaleImage behavior like in Image Control

In my previous post on implementing MultiScaleImage behavior like I have mentioned that I will demonstrate on how to implement a panning behavior like to an Image on SilverLight2 Beta.

In this post I will implement panning behavior like on Image control.

Step 1:

First we have to Subscribe to the following events, MouseLeftButtonUp, MouseLeftButtonDown, MouseMove. We also need to declare two variables that will save the mouse down position and the status of the mouse button(Up/Down).

Variables:

Point lastMousePos = new Point();

bool startPanning = false;

events:

this.MouseLeftButtonUp += new MouseButtonEventHandler(Page_MouseLeftButtonUp);

this.MouseLeftButtonDown += new MouseButtonEventHandler(Page_MouseLeftButtonDown);

this.MouseMove += new MouseEventHandler(Page_MouseMove);

Step 2:

In the MouseLeftButtonDown event we need to save the status of our two newly added variables:

void Page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

    startPanning = true;

    lastMouseDownPos = e.GetPosition(this.MainImage);

}

 

Step 3:

The MouseMove event, in this event we will have to handle the Transform of the Image while the mouse is still moving. Since the code also support Zooming there are two cases of Transformation, when there is ZoomIn/ZoomOut and no zooming. The no zooming section of is the basic of our transformation and it will handle moving the Image around the page. It looks something like this:

void Page_MouseMove(object sender, MouseEventArgs e)

{

    if (!startPanning)

    {

        return;

    }

 

    Transform currentTransform;

 

    currentTransform = new TranslateTransform();

    ((TranslateTransform)currentTransform).X = (e.GetPosition(this).X - lastMouseDownPos.X);

    ((TranslateTransform)currentTransform).Y = (e.GetPosition(this).Y - lastMouseDownPos.Y);

 

You may have noticed that we have to subtract the current mouse position - e.GetPosition(this) with the mouse original left button position - lastMouseDownPos. This is needed to keep the relative position of inside the Image control.

Now we have to handle the mouse position in ZoomIn/ZoomOut mode:

if (zoom != 1)

{

   TransformGroup group = new TransformGroup();

 

   ScaleTransform scaleTransform = new ScaleTransform();

   ((ScaleTransform)scaleTransform).CenterY = lastMouseDownPos.Y;

   ((ScaleTransform)scaleTransform).CenterX = lastMouseDownPos.X;

   ((ScaleTransform)scaleTransform).ScaleX = zoom;

   ((ScaleTransform)scaleTransform).ScaleY = zoom;

 

   group.Children.Add(scaleTransform);

   group.Children.Add(currentTransform);

   currentTransform = group;

}

 

In ZoomIn/ZoomOut we need to add the special Transform to a TransformGroup since we are using two Transformation one for the location of the Image and one for the Zooming.

Apply the Transformation to the Image :

MainImage.RenderTransform = currentTransform;

Step 4:

On the MouseLeftButtonUp event we need to clear the Variables - set the lastMousePos to empty and the startPanning to false.

That's it.

I have added the source code.

Enjoy!

SilverLight 2 Beta Quick Tip - FullScreen

In the previous version of SilverLight we could enter FullScreen mode in our Content using BrowserHost.IsFullScreen.

In SilverLight 2 Beta we no longer have BrowserHost, Instead we can use:

App.Current.Host.Content.IsFullScreen = true;

I have added a source code Sample

Enjoy!

SliverLight2 Beta Quick Tip: Implement MultiScaleImage behavior like in Image Control

Using MultiScaleImage control we get a vivid user friendly image manipulation experience in this quick tip I will demonstrate how to provide the same experience using Image control in SilverLight 2 Beta.

In the Expression Blend Blog we can find the source code on how to implement Zooming using MultiScaleImage I have used this code and replaced the MultiScaleImage with Image:

<Grid x:Name="LayoutRoot" Background="White">

    <Image Width="770" Height="570" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="MainImage"/>

</Grid>

*Notice* I didn't provided source for our Image.

And in the Code file I have used ScaleTransform:

public Page()

{

    InitializeComponent();

 

    this.MouseMove += delegate(object sender, MouseEventArgs e)

    {

        this.lastMousePos = e.GetPosition(this.MainImage);

    };

    this.MouseLeftButtonUp += new MouseButtonEventHandler(Page_MouseLeftButtonUp);

    new MouseWheelHelper(this).Moved += delegate(object sender, MouseWheelEventArgs e)

    {

        if (e.Delta > 0)

        {

            zoom *= 1.2;

        }

        else

        {

            zoom /= 1.2;

        }

 

        ScaleTransform scaleTransform = new ScaleTransform();

        scaleTransform.CenterY = this.lastMousePos.Y;

        scaleTransform.CenterX = this.lastMousePos.X;

        scaleTransform.ScaleX = zoom;

        scaleTransform.ScaleY = zoom;

 

        MainImage.RenderTransform = sc;

    };

}

Using this code you will have the same experience.

In my next post I will try to provide Panning Behavior.

Source Code

Enjoy!  

Create your own Designer or Introduction To Custom Designers - Part 3: SmartTags and Source Code.

As I promised I will supply the source code for the Designer and I will explain about SmartTags, SmartTags enable us easier access to our control an extended to UI.

So SmartTags enable us to access designated operation to our control.

How to create SmartTas:

Step 1:

In my previous session I have demonstrated how to create a Custom Designer, now all you have to do to add SmartTags to your control is to override the ActionLists property of your desginer.

private DesignerActionList m_DesignerActionList;

private DesignerActionListCollection m_ActionLists;

public override DesignerActionListCollection ActionLists

{

    get

    {

        if(m_ActionLists == null)

        {

            m_ActionLists = new DesignerActionListCollection();

            m_DesignerActionList = new MyDesignerActionList(this.Control);

            m_ActionLists.Add(m_DesignerActionList);

        }

        return m_ActionLists;

    }

}

As you may have notice I have created my own implementation of the DesignerActionList class, the new implementation contains the definition of SmartTags abilities exposed by my new DesignerActionList class.

Step 2: Add abilities to your DesignerActionList

To add new SmartTags all you have to do is to override the GetSortedActionItems method and add the Method to be Invoked when the SmartTag is invoked. By adding DesignerActionItemCollection a DesignerActionMethodItem we will Invoke a method.

public override DesignerActionItemCollection GetSortedActionItems()

{

    DesignerActionItemCollection items = new DesignerActionItemCollection();

    items.Add(new DesignerActionMethodItem(this,

                "ImageLocation", "ImageLocation",true));

 

    return items;

}

Now when we will design our control we will be able to use SmartTags.

designerVerb

I have Included source code for our designer.  

 SourceCode

That's it.

*njoy!

Create your own Designer or Introduction To Custom Designers - Part 2: UI, Glyphs

In my last post I have demonstrated how to create your own Designer, in this post I will continue on demonstrating on how to create your own Designer.

My goal in this series of posts is to explain how to create and extended Designers. For this reason I have created a sample. This plain sample is a UserControl that contains an PictureBox and a Label. Using many of this controls can be a bit frustrating, since we can change the Image of the PictureBox without encapsulate the Image Property. As I mention in my last post we would like to avoid this. This is just a simple example of how to use and extend your Control Designer.

This is how it looks:

control101

The UI in your Designer is implemented by Glyphs, each on of your Glyphs is basically a UI access point that during designing you can use to manipulate your control with.

Step 1: Create a Glyph, first you must inherit from the Glyph class, our Implementation to the Glyph should contains reference to the ControlDesigner, Adorner and the various services. This will help our work in designing our Control.

public class PictureSelectionGlyph : Glyph

{

    //References to services that we will need.

    private BehaviorService m_BehaviorService = null;

    private IComponentChangeService m_ComponentChangeService = null;

    private ISelectionService m_SelectionService = null;

    //The designer reference

    private IDesigner m_ComponentDesigner = null;

    //The adorner reference.

    private Adorner m_adorner = null;

    //The control that is being designed.

    private Control m_relatedControl = null;

    // This defines the bounds used for hit testing.

    protected Rectangle m_HitTestBoundsValue;

    // This is the cursor returned if hit test is positive.

    protected Cursor hitTestCursor = Cursors.Hand;

 

All of these arguments are pass to the glyph by the designer so all the extra work we have to do is to keep reference to it.

public PictureSelectionGlyph(BehaviorService behaviorService, IComponentChangeService changeService,

            ISelectionService selectionService,IDesigner relatedDesigner,Adorner anchorAdorner): base(new PictureSelectorBehavior(relatedDesigner))

{

Step 2: Painting our Glyph. The glyph is a UI that is painted by GDI+, so we have to make sure that the glyph is painted in the right way (Location, Size...). First we must decide how we want our glyph to look like. Keep in mind that glyphs are only the access points and should not be to fancy that will shadow the control. this is how it should look like:

You may have notice that we have to calculate the location and size of our Glyph. In my example I have painted the glyph in the middle of the control that been Designed.

//This method renders the PictureSelectionGlyph as a filled rectangle,

//in the center of the designed control.

public override void Paint(PaintEventArgs e)

{

     using (Brush b = new SolidBrush(Color.DarkRed))

     {

         Pen p = new Pen(b, 2f);

         e.Graphics.DrawRectangle(p, Bounds);

         using (Brush fillBrush = new LinearGradientBrush(this.Bounds, Color.DarkRed, Color.Gold, 180f))

         {

             e.Graphics.FillRectangle(fillBrush, Bounds);

         }

     }

}

 

Step 3: Assigning Behavior to our Glyph.

Great! now We have painted a glyph, what is next? Behavior  is the class that responsible for handling and manipulating our Control.

As you might have noticed in the Glyph class Constructor we have Created a new instance of PictureSelectorBehavior, this class is the behavior class of the Glyph. If Glyph is the looks then the Behavior is the Brains.

//This Behavior specifies mouse and keyboard handling when

//Glyph is active. This happens when PictureSelectionGlyph.GetHitTest returns a non-null value.

internal class PictureSelectorBehavior : Behavior

{

   private IDesigner m_relatedDesigner = null;

   private Control m_relatedControl = null;

   private OpenFileDialog m_openFileDialog;

   internal PictureSelectorBehavior(IDesigner relatedDesigner)

   {

      this.m_relatedDesigner = relatedDesigner;

      this.m_relatedControl = relatedDesigner.Component as Control;

   }

Our behavior should inherits from Behavior and Initialize in Glyph Constructor

We would like to keep reference for our Designer, Control this will help us manipulate our Designed Control.

All that's left is to decide how our control react, in my case I had overridden the OnMouseDoubleClick:

public override bool OnMouseDoubleClick(Glyph g, MouseButtons button, Point mouseLoc)

{

    if (button != MouseButtons.Left)

       return false;

   PropertyDescriptor bounds = TypeDescriptor.GetProperties(g)["Bounds"];

   if (((Rectangle)bounds.GetValue(g)).Contains(mouseLoc))

   {

       if(BehaviorOenFileDialog.ShowDialog(m_relatedControl)  == DialogResult.OK)

       {

           PropertyDescriptor imageLocationPropertyDescriptor = TypeDescriptor.GetProperties(m_relatedControl)["ImageLocation"];

               imageLocationPropertyDescriptor.SetValue(m_relatedControl, BehaviorOenFileDialog.FileName);

       }

       return true;

   }

   return base.OnMouseDown(g, button, mouseLoc);

}

In the OnMouseDoubleClick we check that the event occurs on the Glyph bounds if so we perform the desire action, In my case I open a dialog that will ask us to choose the physical location of the Image In our PictureBox  - Sweet!.

Note: If you want that the Image will be saved in the Resources of our project use PropertyDescriptor to set the new value of the Image property of PictureBox.

This is how it looks in Design mode:

designer101

DoubleClick to open the dialog and select a new Image.

* Source Code will be available soon.

Next post will feature new abilities such as Verbs and SmartTags.

*njoy!

Create your own Designer or Introduction To Custom Designers - Part 1: Designer

Working with Winforms Designer and UserControls has always been a bit complicated, we could never get an easy access to the UserControls unique properties when designing our Control. We only had one option to access Properties via the Properties Window.

To understand better how Designers works please visit The Perfect Host.

In this post I will demonstrate how we can easily create and adapt a Custom Designer for a New UserControl

This figure demonstrate how a Button is Contained by a Form At RunTime.

When we are working In DesignTime each control we design has an Designer Attribute  attached to it.

For example this is how a Button Designer attribute is defined:

[Designer("System.Windows.Forms.Design.ButtonBaseDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), SRDescription("DescriptionButton"), ClassInterface(ClassInterfaceType.AutoDispatch), ComVisible(true)]

public class Button : ButtonBase, IButtonControl

{

In this example I have created a UserControl that contains a PictureBox. I may use this Control in many different Forms  or other UserControl. The main issue with my UserControl is that to access the PictureBox and define in each UserControl a different Image is a bit tricky. I can encapsulate the Image property from the PictureBox and use it as I uses my UserContol using the Properties Window.

The following example demonstrate how to access the Image Property from the PictureBox.

public class PictureDemoControl : UserControl

{

    private PictureBox pictureBox1;

    public Image PictureImage

    {

        get { return pictureBox1.Image; }

        set { pictureBox1.Image = value;}

    }

This is how we can edit the Image property using Properties Window:

fig04

This solution is nice but does not enable access to the Image property using anything other then Properties windows in Design-Time, beside that now the Image Property is accessible to all.

To avoid this we can create and define a new Designer for the user control, this designer will enable easy access in Design-Time.

Step 1: Create your own designer.

Your Designer should Inherit from ControlDesigner this will let you extend the basic Designer Behavior. Your custom ControlDesigner  will contain at least one Adorner, the designer should also initialize this services: IComponentChangeService, ISelectionService, BehaviorService. All this services are essential and will provide us access to the Designed Control.    

The Designer also contains Glyphs, Glyph is the UI that will be painted when your component is selected. Using the glyph you can basically manipulate and design your Control in Design-Time. I strongly recommend that you will not use Adorner for each one of your Glyphs - that may be too costly. Try dividing your Glyphs into logical groups and then assign each group with a different Adorner .

This is how your Designer Class should look like:

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]

    internal class MyPictureDesigner : ControlDesigner

    {

        // This adorner holds the glyphs

        private Adorner m_pictureSelectorAdorner = null;

        // References to designer services

        private IComponentChangeService m_componentChangeService = null;

        private ISelectionService m_selectionChangeService = null;

        private BehaviorService m_behaviorService = null;

        private void InitializeServices()

        {

            // Reference to IComponentChangeService.

            this.m_componentChangeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService;

            //Reference  to ISelectionService.

            this.m_selectionChangeService = GetService(typeof(ISelectionService)) as ISelectionService;

            //Reference  to BehaviorService.

            this.m_behaviorService = GetService(typeof(BehaviorService)) as BehaviorService;

            this.m_pictureSelectorAdorner = new Adorner();

            this.m_behaviorService.Adorners.Add(this.m_pictureSelectorAdorner);

        }

        public override void Initialize(IComponent component)

        {

            base.Initialize(component);

            InitializeServices();

            /*this is where we will Assign the Adorner with Glyph*/

More about Glyphs and Behavior at Part 2.

Happy New Year!

WPF Tip: Slider Indication

In my last post I have demonstrated how to create your own style into the Simple Style, In this post I will show how to provide your newly created Slider with a unique status Indication.

Last time we created our own style using Expression Design and applying the pre-fabricated design into the Simple Style . As you can see there are two styles relevant to Increase Decrease behavior: SimpleScrollRepeatButtonStyle.

 

<Track Grid.Row="1" x:Name="PART_Track">

  <Track.Thumb>

    <Thumb Style="{DynamicResource SimpleSliderThumb}"/>

  </Track.Thumb>

  <Track.IncreaseRepeatButton>

    <RepeatButton Style="{DynamicResource SimpleScrollRepeatButtonStyle}" Command="Slider.IncreaseLarge"/>

  </Track.IncreaseRepeatButton>

  <Track.DecreaseRepeatButton>

    <RepeatButton Style="{DynamicResource SimpleScrollRepeatButtonStyle}" Command="Slider.DecreaseLarge"/>

  </Track.DecreaseRepeatButton>

</Track>

Step 1: Rename the style to differentiate theme from one another:

 

<Track Grid.Row="1" x:Name="PART_Track">

  <Track.Thumb>

    <Thumb Style="{DynamicResource SimpleSliderThumb}"/>

  </Track.Thumb>

  <Track.IncreaseRepeatButton>

    <RepeatButton Style="{DynamicResource SimpleScrollRepeatButtonStyleIncrease}" Command="Slider.IncreaseLarge"/>

  </Track.IncreaseRepeatButton>

  <Track.DecreaseRepeatButton>

    <RepeatButton Style="{DynamicResource SimpleScrollRepeatButtonStyleDeCrease}" Command="Slider.DecreaseLarge"/>

  </Track.DecreaseRepeatButton>

</Track>

 

Step 2: Create the the two different Styles (remember to keep theme different).

 

<Style x:Key="SimpleScrollRepeatButtonStyleIncrease" TargetType="{x:Type RepeatButton}">

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

        <Setter Property="BorderBrush" Value="Transparent"/>

        <Setter Property="IsTabStop" Value="false"/>

        <Setter Property="Focusable" Value="false"/>

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="{x:Type RepeatButton}">

                    <Grid>

                                <Path x:Name="DownloadProgressSlider" Width="736" Height="6.42206" Canvas.Left="25.6802" Canvas.Top="498.937" Stretch="Fill" Data="F1 M 25.6802,498.937L 761.68,498.937L 761.68,505.359L 25.6802,505.359L 25.6802,498.937 Z ">

                                <Path.Fill>

                                    <RadialGradientBrush RadiusX="0.5" RadiusY="57.3025" Center="0.5,0.5" GradientOrigin="0.5,0.5">

                                        <RadialGradientBrush.RelativeTransform>

                                            <TransformGroup/>

                                        </RadialGradientBrush.RelativeTransform>

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

                                        <GradientStop Color="#FF77E1FE" Offset="0.429688"/>

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

                                    </RadialGradientBrush>

                                </Path.Fill>

                            </Path>

                    </Grid>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>

 

    <Style x:Key="SimpleScrollRepeatButtonStyleDecrease" TargetType="{x:Type RepeatButton}">

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

        <Setter Property="BorderBrush" Value="Transparent"/>

        <Setter Property="IsTabStop" Value="false"/>

        <Setter Property="Focusable" Value="false"/>

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="{x:Type RepeatButton}">

                    <Grid>

                        <Path x:Name="DownloadProgressSlider" Width="736" Height="6.42206" Canvas.Left="25.6802" Canvas.Top="498.937" Stretch="Fill" Data="F1 M 25.6802,498.937L 761.68,498.937L 761.68,505.359L 25.6802,505.359L 25.6802,498.937 Z ">

                            <Path.Fill>

                                <RadialGradientBrush RadiusX="0.5" RadiusY="57.3025" Center="0.5,0.5" GradientOrigin="0.5,0.5">

                                    <RadialGradientBrush.RelativeTransform>

                                        <TransformGroup/>

                                    </RadialGradientBrush.RelativeTransform>

                                    <GradientStop Color="Transparent" Offset="0"/>

                                    <GradientStop Color="Transparent" Offset="1"/>

                                </RadialGradientBrush>

                            </Path.Fill>

                        </Path>

                    </Grid>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>

Instead of looking like this:

simplesplider

Now your Slider should look something like this:

VistaSlider 

Now we can tell the progress on our slider.

 

Enjoy!

WPF Tip: Create your own unique style

When developing a new UserControls you usually would like to enable your own custom style, I found the following way very useful.

This example shows you how to create a Slider:

I used Microsoft Expression Design to create my own thumb for a Slider control.

After you had finished drawing your new Thumb, export the XAML using the Microsoft Expression Design.

Export using the following way:

exportXAML 

Select Resource dictionary, in the Group By select Layers this will export the Drawing Created by you into the XAML and will differentiate elements in the drawing by Layers. - Now you can use the drawing as a ResourceDictionary 

If you like to edit you drawing in Microsoft Expression Blend select the export to Canvas, select Export editable TextBlocks if your drawing contains Text.

1. Create your own ResourceDictionary and copy your XAML into it.

2. Copy the simple style User Control XAML into your ResourceDictionary. This is how it should look like: (I am only replacing the Thumb in the slider)

<Track.Thumb>

     <Thumb Style="{DynamicResource SimpleSliderThumb}"/>

</Track.Thumb>

        ...

    <!--Simple Simple SliderThumb - The Thumb is the draggable part of a Slider-->

    <Style x:Key="SimpleSliderThumb" d:IsControlPart="True" TargetType="{x:Type Thumb}">

        <Setter Property="SnapsToDevicePixels" Value="true"/>

        <Setter Property="Height" Value="14"/>

        <Setter Property="Width" Value="14"/>

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="{x:Type Thumb}">

                    <Grid>

                        <Ellipse x:Name="Ellipse" Fill="{DynamicResource NormalBrush}"

                        Stroke="{DynamicResource NormalBorderBrush}" StrokeThickness="1"/>

                    </Grid>

                    <ControlTemplate.Triggers>

                        <Trigger Property="IsMouseOver" Value="True">

                            <Setter Property="Fill"
                                    Value
="{DynamicResource MouseOverBrush}"

                                    TargetName="Ellipse"/>

                        </Trigger>

                        <Trigger Property="IsEnabled" Value="false">

                            <Setter Property="Fill"
                                    Value
="
{DynamicResource DisabledBackgroundBrush}"

                            TargetName="Ellipse"/>

                        </Trigger>

                    </ControlTemplate.Triggers>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>

 

3. Now take your own custom style and replace the style relevant.

<RadialGradientBrush x:Key="Path1Brush" RadiusX="0.684617" RadiusY="0.684615"

Center="0.492308,1.16154"GradientOrigin="0.492308,1.16154">

  <RadialGradientBrush.RelativeTransform>

     <TransformGroup>

       <RotateTransform CenterX="0.492308" CenterY="1.16154" Angle="-90"/>

     </TransformGroup>

  </RadialGradientBrush.RelativeTransform>

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

    <GradientStop Color="#FF9B4444" Offset="0.429688"/>

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

  </RadialGradientBrush>

  <RadialGradientBrush x:Key="Path2Brush" RadiusX="0.874381" RadiusY="0.488538"

    Center="0.4988,0.953051" GradientOrigin="0.4988,0.953051">

    <RadialGradientBrush.RelativeTransform>

     <TransformGroup>

       <RotateTransform CenterX="0.4988" CenterY="0.953051" Angle="-90"/>

     </TransformGroup>

     </RadialGradientBrush.RelativeTransform>

       <GradientStop Color="#00FFFCF9" Offset="0.68457"/>

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

  </RadialGradientBrush>

<ControlTemplate TargetType="{x:Type Thumb}">

  <Grid>

    <Canvas Width="11.6" Height="11.6477" Background="Transparent" >

      <Path x:Name="Path1" Fill="{DynamicResource Path1Brush}" Width="11.6"

           Height="11.6" Canvas.Left="0" Canvas.Top="0.0477295" Stretch="Fill"

           Data="F1 M 5.80002,0.0477295C 9.00323,0.0477295 11.6,2.64435

           11.6,5.84775C 11.6,9.05096 9.00323,11.6477 5.80002,11.6477C 2.5968,

           11.6477 0,9.05096 0,5.84775C 0,2.64435 2.5968,0.0477295 5.80002,0.0477295"/>

      <Path x:Name="Path2" Fill="{DynamicResource Path2Brush}" Width="11.526"

        Height="6.43983" Canvas.Left="0.0370712" Canvas.Top="0" Stretch="Fill"

       Data="F1 M 5.80006,0C 8.98283,0 11.5631,2.58005 11.5631,5.76297C 11.5631,7.30338

        8.67518,5.44769 5.88872,5.49701C 2.91804,5.5495 0.0370712,

        7.40518 0.0370712,5.76297C 0.0370712,2.58005 2.61729,0 5.80006,0"/>

    </Canvas>

  </Grid>

  <ControlTemplate.Triggers>

    <Trigger Property="IsMouseOver" Value="True">

      <Setter Property="Fill" Value="{DynamicResource Path1Brush}" TargetName="Path1"/>

    </Trigger>

    <Trigger Property="IsEnabled" Value="false">

      <Setter Property="Fill" Value="{DynamicResource Path2Brush}" TargetName="Path2"/>

    </Trigger>

  </ControlTemplate.Triggers>

</ControlTemplate>

 

 

 

 

 

 

 

4. Link the ResourceDictionary to your Simple Style:

 

 

image

 

5. Create a slider and apply the style on to the slider like so:

<Slider HorizontalAlignment="Right" Margin="0,0,141,40" VerticalAlignment="Bottom"

  Width="177" x:Name="VistaSlider1" Style="{DynamicResource VistaSlider}">

  <Slider.Resources>

  <ResourceDictionary>

    <ResourceDictionary.MergedDictionaries>

    <ResourceDictionary Source="ResourceDictionary1.xaml"/>

   </ResourceDictionary.MergedDictionaries>

  </ResourceDictionary>

 </Slider.Resources>

</Slider>

You should end up with something looking like this:

VistaToolBar

Enjoy!

 

Intro

In this blog will try to feature insights about developing Winforms, Designers, Controls and many solutions I had cooked up.

I will also explorer useful tools and technologies from Microsoft.

Posted: Dec 03 2007, 12:05 AM by Yogev | with no comments
תגים: