Windows Phone Support

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Thursday, 24 September 2009

Building a Dial Control

Posted on 08:48 by Unknown
A friend posed a question a few weeks back about implementing a dial control. I found a few but they seemed problematic so I decided it can't possibly be that hard. So the idea is a control with a custom event for dial position change that I can add templates etc to change the look and feel of the control to any kind of dial I want and bind an event handler to so that in can control say volumn. I posted how to implement a custom event last week so I'll focus specifically on the rest of the dial control. Lets start with the template in Generic.xaml.

<Style TargetType="DialTest:Dial">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DialTest:Dial">
<Grid x:Name="Knob" Background="Transparent" >
<ContentPresenter x:Name="Background" Content="{TemplateBinding KnobBackground}"/>
<ContentPresenter x:Name="DialKnob" Content="{TemplateBinding KnobFace}" RenderTransformOrigin="0.5,0.5" >
<ContentPresenter.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="DialAngle" Angle="0" />
</TransformGroup>
</ContentPresenter.RenderTransform>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

So from this template we can see that the control will have a wrapper grid to force content to be resized as set and two content presenters one for the background and one for the dial and further a rotate transform on the dial so we can make it turn. As noted these content presenters imply that we have two dependency properties for the dial face and background but we will also have DP's for setting the start or minimum or max angle setting of the dial (0 to 360 degrees).

In our constructor then we set our template and then OnApplyTemplate() we wire things together like so:

Knob = ((Grid)GetTemplateChild("Knob"));
DialAngle = ((RotateTransform)GetTemplateChild("DialAngle"));

Knob.MouseLeftButtonUp += new MouseButtonEventHandler(Knob_MouseLeftButtonUp);
Knob.MouseLeave += new MouseEventHandler(Knob_MouseLeave);
Knob.MouseLeftButtonDown += new MouseButtonEventHandler(Knob_MouseLeftButtonDown);
Knob.MouseMove += new MouseEventHandler(Knob_MouseMove);

base.OnApplyTemplate();

if (Minimum > 0 && Minimum < 360)
{
SetPosition(Minimum);
}

this wires our internal events we use to make the wiring work. What we are doing todo is on mouse down we will calculate the angle of that related to the control and then turn the dial to that position. we then fire off the angle changed event or custom event. The hard part turned out to the just figuring out the math and it turns out that this not the best method 'mathmatically' speaking but this works well. Once get a point from the mouse down we do this to get the relative angle:

double TheDiameter = Knob.ActualWidth;
double CurrentHeight = Knob.ActualHeight;

double Radius = TheDiameter / 2;

double AngleOfRotation = AngleOfRotationQuadrant(TheDiameter, CurrentHeight, NewPoint);

//int DialQuadrant = 1;
if ((NewPoint.X > Radius) && (NewPoint.Y <= Radius))
{
//DialQuadrant = 2;
AngleOfRotation = 90.0 + (90.0 - AngleOfRotation);
}
else if ((NewPoint.X > Radius) && (NewPoint.Y > Radius))
{
//DialQuadrant = 4;
AngleOfRotation = 180.0 + AngleOfRotation;
}
else if ((NewPoint.X < Radius) && (NewPoint.Y > Radius))
{
//DialQuadrant = 3;
AngleOfRotation = 270.0 + (90.0 - AngleOfRotation);
}
return AngleOfRotation;

Basically we calculate 90 degress of position for he dial face quadrant that the event was in and then add the relative additional quadrants as needed to get the correct angle. getting the quadrant goes like this:

double DialRadius = CurrentWidth / 2;

Point CenterPoint = new Point(DialRadius, CurrentHeight / 2);
Point StartPoint = new Point(0, CurrentHeight / 2);

double TriangleTop = Math.Sqrt(ToThePowerOfTwo(NewPoint.X - CenterPoint.X) + ToThePowerOfTwo(CenterPoint.Y - NewPoint.Y));

double TriangleHeight = (NewPoint.Y > CenterPoint.Y) ? NewPoint.Y - CenterPoint.Y : CenterPoint.Y - NewPoint.Y;

return ((TriangleHeight * Math.Sin(90.0)) / TriangleTop) * 100;

now we can set the angle in 'SetPosition(); like this:
if (Minimum > 0 && Max > 0 && Minimum < 360 && Max <= 360 )
{
if (AngleOfRotation < Minimum)
{
AngleOfRotation = Minimum;
}
if (AngleOfRotation > Max)
{
AngleOfRotation = Max;
}
}

DialAngle.Angle = AngleOfRotation;

OnPositionChanged(new DialEventArgs(AngleOfRotation));

the last line being our custom event. and poof it works... So in xaml using the control might look like this:

<cc:Dial x:Name="NewKnobControl" Height="100" Width="100" PositionChangedEvent="NewKnobControl_PositionChangedEvent" Minimum="45.0" Max="135" >
<cc:Dial.KnobFace>
<Grid >
<Ellipse Fill="Aquamarine" />
<Rectangle x:Name="Indicator" Height="10" Width="49" Fill="Blue" Margin="1,45,50,45" />
</Grid>
</cc:Dial.KnobFace>
</cc:Dial>

nice and simple, needs some design love but you get the point. The dial control code will be up on HackingSilverlight.codeplex.com some time this week.
Email ThisBlogThis!Share to XShare to FacebookShare to Pinterest
Posted in controls, silverlight 3 | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • Silverlight Best Practices
    So in a web application from time immemorial the bottle necks have been the database access and the ability of the servers to server up wha...
  • JavaScript Class Structures
    So 8 years ago or so I worked for this company and was hired to fix and admin tool they wrote in JavaScript... The system had 10's of t...
  • Silverlight Eval Function
    So this is a huge hack and the only purpose really for me is to be able to say I can do it and YOU can too albeit don't do this... I kno...
  • Flex Flash Smack Down and maybe some Silverlight
    Last night was the Seattle Designer Developer Interaction Group (user group) meeting. its a user group focused on UX and the designer devel...
  • Finally a Simple MVVM in Silverlight
    So a week or so ago I ran across this article/post by Jeremiah Morrill ( MVVM-for-Tarded-Folks-Like-Me-or-MVVM-and-What-it-Means-to-Me.aspx ...
  • Asynchronous Image Loading in Silverlight
    So one task that was bugging me today was doing image loading asynchronously so as to not drag the app down. Now there are some 'xaml...
  • Silverlight Hosting in WPF
    Ok so we know this has been done. Yawn, and it can be done any number of ways from hacking it in a browser control but actually doing it in...
  • Silverlight Connections - Vegas Nov 1-4
    got asked to speak at SilverlightConnections in Vegas in Nov. :) topics include: 'Breaking Down Walls – The Story of Getting designers a...
  • Turning XAML into an image (jpg) in WP7 isolated storage and to the Phone Media Library
    So one thing that has been kind a trick since the old avalon then wpf days was to be able to can a snap shot of part of the visual tree and ...
  • Silverlight TV Episode 3: Multi-Touch 101 with Silverlight
    John interviews Silverlight MVP David Kelley (thats me) about developing multi-touch applications in Silverlight. I discuss the types of mul...

Categories

  • .net
  • 3D
  • adam
  • adcontrol
  • adobe
  • agile
  • algorithms
  • analytics
  • andrew
  • android
  • Animating Panel Base
  • animation
  • apache
  • apphub
  • apple
  • apps
  • architecture
  • ariel
  • article
  • ASP.NET
  • balder
  • bar camp
  • behavior
  • best practices
  • beta 1
  • beta 2
  • bi
  • bitmap effect
  • blend
  • blendables
  • blog
  • book
  • book review
  • bookreview
  • browser
  • brush
  • build
  • c#
  • channel9
  • cmm
  • codebrowser
  • codemagazine
  • codemash
  • codeplex
  • color
  • com
  • command
  • composite
  • controls
  • Craig
  • crossfader
  • csharp
  • CSS
  • custom event
  • Dan
  • data
  • datagrid
  • davidjkelley
  • davidkelley
  • ddj
  • Deep Zoom
  • dependencyproperty
  • design
  • design patterns
  • designers
  • devconnections
  • developer
  • developers
  • devin
  • DevTeach
  • dispatcher
  • dotnetslackers
  • dp
  • Dr WPF
  • easy
  • eclipse
  • ecma
  • education
  • einari
  • ET
  • event
  • exchange
  • expression
  • facebook
  • facing blend
  • Faisal
  • firestarter
  • flash
  • flex
  • font
  • free
  • fun
  • futures
  • gadget
  • game
  • games
  • gesture
  • google
  • Grid
  • hack
  • hacking
  • hacking phone 7
  • Hacking Silverlight
  • hard
  • hero
  • holst
  • howto
  • hta
  • HTML
  • html5
  • HTMLAppHostFramework
  • htmlapplication
  • ia
  • identitymine
  • IE
  • IE 8
  • iis
  • images
  • indexability
  • INETA
  • Infragistics
  • Integrator
  • interact
  • iphone
  • isolatedstorage
  • issues
  • itemscontrol
  • ixda
  • jared
  • jason cook
  • javascript
  • jeremiah
  • jobi
  • jobs
  • johnpapa
  • jordan
  • josh
  • jscript
  • json
  • Karim
  • kaxaml
  • kellywhite
  • keynote
  • KimSchmidt
  • law of
  • layout
  • linux
  • listbox
  • LOB
  • mac
  • mango
  • manning
  • marketing
  • marketplace
  • math
  • media element
  • media encoder
  • methodology
  • microsoft
  • MIX
  • MIXer
  • mobile
  • monitization
  • monitizationmodels
  • movie link
  • MSDN
  • msdnbytes
  • msdnradio
  • msretail
  • mstag
  • multitouch
  • MVP
  • MVVM
  • Netflix
  • nike
  • nui
  • object oriented
  • OOB
  • out of browser
  • packt
  • panels
  • parchment
  • parchment apps
  • paths
  • PDC
  • peter
  • phone7
  • phone7unleashed
  • phones
  • php
  • Pixel8
  • pixelshader
  • player
  • popfly
  • prediction
  • preemptive
  • preloader
  • presentations
  • radial panel
  • random panel
  • reference
  • requirements
  • retail
  • review
  • ria
  • robby
  • ROI
  • RPS
  • ryan
  • sajiv thomas
  • SCRUM
  • SD2IG
  • Sea Dragon
  • searchability
  • seattle
  • seattlesilverlight
  • seattleslug
  • sebastian
  • services
  • sharepoint
  • sharepoint2010
  • sic
  • side bar gadget
  • Silver Dragon
  • silverlight
  • silverlight 1
  • silverlight 2
  • silverlight 2.0
  • silverlight 3
  • silverlight 4
  • silverlight insiders
  • silverlight show
  • silverlight4
  • silverlight5
  • Silverlight5
  • silverlightconnections
  • silverlightcream
  • silverlighttv
  • simon
  • simonsaid
  • simple
  • SMART
  • snack
  • stackpanel
  • stevejobs
  • streaming
  • stuartcelarier
  • surface
  • symbian
  • tard
  • teched
  • TED
  • testing
  • textbox
  • TFS
  • threading
  • tim
  • tip
  • tiredallover
  • tool
  • touch
  • touchtag
  • training
  • twitter
  • ui
  • uml
  • usergroup
  • UX
  • uxdesign
  • vagas
  • victor
  • video
  • videos
  • vista
  • visual studio
  • volta
  • VS
  • vsm
  • WCF
  • win8
  • Windows7
  • windows8
  • windowsphone
  • windowsphone7
  • wirestone
  • workflow
  • wp7
  • wp7dev
  • WPF
  • wrappanel
  • wrox
  • xaml
  • xap
  • XML
  • xna
  • zen
  • zphone

Blog Archive

  • ►  2012 (5)
    • ►  May (1)
    • ►  April (2)
    • ►  March (1)
    • ►  February (1)
  • ►  2011 (29)
    • ►  December (2)
    • ►  November (2)
    • ►  October (3)
    • ►  September (1)
    • ►  August (5)
    • ►  June (5)
    • ►  May (2)
    • ►  March (1)
    • ►  February (5)
    • ►  January (3)
  • ►  2010 (51)
    • ►  December (5)
    • ►  November (4)
    • ►  October (3)
    • ►  September (5)
    • ►  August (3)
    • ►  June (3)
    • ►  May (6)
    • ►  April (3)
    • ►  March (9)
    • ►  February (3)
    • ►  January (7)
  • ▼  2009 (75)
    • ►  December (3)
    • ►  November (2)
    • ►  October (3)
    • ▼  September (7)
      • Building a Dial Control
      • Blend/Catalyst Smack Down?
      • The Gu a Silveright firestarter
      • Don't Forget about Silverlight Week
      • 64bit Surface Hack
      • Custom Control Development: Simple code guidelines
      • Custom Events on Silverlight Controls
    • ►  August (4)
    • ►  July (7)
    • ►  June (9)
    • ►  May (12)
    • ►  April (13)
    • ►  March (8)
    • ►  February (2)
    • ►  January (5)
  • ►  2008 (119)
    • ►  December (8)
    • ►  November (10)
    • ►  October (12)
    • ►  September (10)
    • ►  August (11)
    • ►  July (4)
    • ►  June (10)
    • ►  May (5)
    • ►  April (3)
    • ►  March (11)
    • ►  February (8)
    • ►  January (27)
  • ►  2007 (34)
    • ►  December (6)
    • ►  November (11)
    • ►  October (17)
Powered by Blogger.

About Me

Unknown
View my complete profile