Click here to Skip to main content
13,147,591 members (29,950 online)
Click here to Skip to main content
Add your own
alternative version

Stats

30.6K views
931 downloads
46 bookmarked
Posted 4 Dec 2015
MIT

WPFSpark v1.2

, 15 Mar 2016
Rate this:
Please Sign up or sign in to vote.
The next version of the useful WPF controls is here

WPFSpark v1.2

At last, it's here! After a really long gap of nearly 4 years, I am happy to announce that the next version of WPFSpark is finally released. :)

What's new in WPFSpark v1.2

In this section I will be providing a summary of new features and modifications made to the WPFSpark controls so that you can adapt your code quickly and integrate new features with ease. For WPFSpark v1.1, I had written several articles, explaining in detail, how each of the controls was designed and implemented. You can see those articles here (WPFSpark: M of N series). I intend to update these articles as soon as possible. For the time being, this article should bring you up to speed. All the code has been ported to .NET framework 4.6.1 using C# 6.0.

SprocketControl

None of the existing dependencies have been changed. However, in order to give the user more freedom, two new dependency properties have been added - InnerRadius and OuterRadius. They govern the length of the spoke. They are represented as a ratio of the radius of the inner circle and outer circle (between which the spokes lie) with the width of the SprocketControl, respectively.

Dependency PropertyTypeDescriptionDefault Value
InnerRadiusDoubleGets or sets the ratio of the Inner Radius to the Width of the SprocketControl.0.175
OuterRadiusDoubleGets or sets the ratio of the Outer Width to the width of the SprocketControl.0.3125

ToggleSwitch

When WPFSpark v1.1 was released, users reported of a memory leak (it can be found here) in the FluidMoveBehavior. ToggleSwitch uses FluidMoveBehavior in order to animate its content when its IsChecked state changes. I looked into various possible solutions to solve this issue but none of them proved satisfactory. Then I decided to remove ToggleSwitch's dependency on FluidMoveBehavior completely. The content of ToggleSwitch is hosted inside a Grid and FluidMoveBehavior is used to animate the movement of the content from one column of the Grid to another. So instead of hosting the content inside a Grid, they are now hosted in a Canvas and instead of using the FluidMoveBehavior, DoubleAnimation is used to animate the Margin of the content.

While implementing this change, it made me look deeper into the ToggleSwitch code and also the issues and suggestions reported by users in the CodePlex site. It thus triggered several other changes (and ultimately a huge rewrite) in order to make ToggleSwitch easier to use while eliminating potential issues (both visual and in code). Here are the changes:

By default, the IsThreeState property is set to False as ToggleSwitch supports only two states for the IsChecked property - True and False. Setting the IsChecked property will not have any visual effect on ToggleSwitch.

The following Dependency Properties have been removed

  • TargetColumnInternal
  • ThumbGlowColor - replaced by ThumbGlowBrush
  • ThumbShineCornerRadius
  • ThumbWidth - replaced by ThumbWidthRatio. ThumbWidth is now a read-only property which represents the actual width of the Thumb.

The following read-only Dependency Properties have been added

Dependency PropertyTypeDescription
CheckedMarginThicknessGets the calculated Margin of the PART_ContentGrid when the ToggleSwitch is in Checked state.
UncheckedMarginThicknessGets the calculated Margin of the PART_ContentGrid when the ToggleSwitch is in Unchecked state.
ThumbWidthdoubleGets the calculated width of the Thumb.
ThumbHeightdoubleGets the calculated height of the Thumb.
ThumbCornerRadiusCornerRadiusGets the calculated CornerRadius of the Thumb.

The following new Dependency Properties have been added

Dependency PropertyTypeDescriptionDefault Value
CheckedTextEffectEffectGets or sets the effect to be applied on the Checked Text.null
UncheckedTextEffectEffectGets or sets the effect to be applied on the Unchecked Text.null
ThumbGlowBrushBrushGets or sets the Brush for the Glow in the Thumb which is shown when the mouse hovers over the ToggleSwitch.Transparent
ThumbShineBrushBrushGets or sets the Brush for the shine on the Thumb.Transparent
ThumbWidthRatioDoubleGets or sets the ratio of the Width of the Thumb to the Width of the ToggleSwitch. Value Range: 0.1 - 0.9, inclusive.0.4
OptimizeRenderingBooleanGets or sets the property which indicates whether the ClipBorder surrounding the ToggleSwitch should enable OptimizeClipRendering to prevent gaps between the border and the clipped content. Set this value to False, if the ToggleSwitch Background is Transparent or has partial transparency. Otherwise, if the Background is opaque, set this value to True for better rendering..False
OptimizeThumbRenderingBooleanGets or sets the property which indicates whether the ClipBorder surrounding the ToggleSwitch Thumb should enable OptimizeClipRendering to prevent gaps between the border and the clipped content. Set this value to False, if the ToggleSwitch ThumbBackground is Transparent or has partial transparency. Otherwise, if the ThumbBackground is opaque, set this value to True for better rendering..False
AutoThumbWidthRatioBooleanGets or sets the property which indicates whether the ThumbWidthRatio should be automatically calculated based on the Width, Height and BorderThickness of the ToggleSwitch. This property has higher precedence over the ThumbWidthRatio property. If this property is set to true, any value for ThumbWidthRatio, set by the user, will be ignored and ThumbWidth will be equal to ThumbHeight.True

Golden Rules for ToggleSwitch

Although, ToggleSwitch gives you the freedom to set the values of its Dependency Properties from a vast range of values, in order to have the ToggleSwitch render effectively, just follow these golden rules:

  • Provide uniform values for BorderThickness and ThumbBorderThickness
  • BorderThickness and ThumbBorderThickness should be proportionate i.e. if BorderThickness is {a,b,a,b}and ThumbBorderThickness is {c,d,c,d} then (a/b) should be equal to (c/d).
  • Provide uniform values for CornerRadius. If you are providing non-uniform values, try to ensure that the radii are horizontally (e.g. {a,a,b,b} ) or vertically (e.g. {a,b,b,a}) symmetrical.
  • Ensure that the CornerRadius is less than or equal to half of the ToggleSwitch's height.
  • If you have Background and ThumbBackground as non-transparent colors, then set the OptimizeRendering and OptimizeThumbRendering properties to true.
  • Set the AutoThumbWidthRatio to true and let the ToggleSwitch calculate the best ThumbWidth.

In the source code, in the file ToggleSwitch.Generic.xaml, along with the ControlTemplate for ToggleSwitch I have also added several styles which use the template. These style mimic the user experience of Toggle buttons found in Windows 10 and iOS. You must add the ToggleSwitch.Generic.xaml in your App.xaml to gain access to these styles. The list of styles are:

  • ToggleSwitch.UWP.Light.Style - Represents the Windows 10 ToggleButton for light backgrounds.

  • ToggleSwitch.UWP.Dark.Style - Represents the Windows 10 ToggleButton for dark backgrounds.

  • ToggleSwitch.iOS.XXXX.Style - Represents the iOS ToggleButton for light backgrounds where XXXX refers to the accent color.

You can derive from these styles to create your own styles with the accent color of your choice. You can refer to these styles in your XAML in the following way:

<wpfspark:ToggleSwitch Grid.Row="1"

						  Grid.Column="1"

						  HorizontalAlignment="Center"

						  VerticalAlignment="Center"

						  Style="{StaticResource {ComponentResourceKey TypeInTargetAssembly=wpfspark:ToggleSwitch, ResourceId=ToggleSwitch.UWP.Dark.Style}}" />

ClipBorder

ClipBorder class deserves an honorable mention here. ToggleSwitch would not exist if it were not for the ClipBorder class. In WPFSpark v1.1, ClipBorder class derived from Border class and set the Clip property to clip its child within its bounds. However, that did not prove too effective. In certain scenarios, the ClipBorder did not render correctly. For example, when the ClipBorder had a thick border and both the BorderBrush and Background were the same color, you could see a small gap between the border and the background, especially at the round corners. Initially I thought it was due to the Clip Geometry that was being calculated for the ClipBorder's child based on its borders. I tried different solutions (like adding a small tolerance value while calculating the Clip Geometry) but it did not eliminate the issue effectively.

Then I found out that the problem was not with ClipBorder. The Border class also displayed the same behavior.

This made me dig deep into the Microsoft Reference Source for the Border class and come up with an optimized solution of my own. ClipBorder no longer derives from Border class. It now derives from the Decorator class and clips its child more effectively than previously.

FluidWrapPanel

In WPFSpark v1.1, FluidWrapPanel imposed a restriction that all its Children must have the same size (defined by ItemWidth and ItemHeight). One of the top feature requests made by users was to remove this restriction and allow adding Children having different dimensions. Initially, I thought it was difficult to achieve and it would require some crazy code modifications. Then I came up on the idea of using BitMatrix to track the positions of the Children and calculate the placement of a child while it was being dragged. This led to the implementation of the FluidBitMatrix class which replaced the FluidLayoutManager class.

However, there is one restriction - the Children must have dimensions which are multiples of ItemWidth and ItemHeight. I have also added a read-only Dependency Property FluidItems which is an ObservableCollection of the Children. By accessing this property you can obtain the current order of the Children in the FluidWrapPanel and also be notified of changes when a child is dragged to a new location. Another Dependency Property which I have added is the OptimizeChildPlacement which governs the algorithm to calculate the best available position for placing a child in the FluidWrapPanel.

Dependency PropertyTypeDescriptionDefault Value
OptimizeChildPlacementBooleanGets or sets the property that indicates whether the placement of the children is optimized. If set to true, the child is placed at the first available position from the beginning of the FluidWrapPanel. If set to false, each child occupies the same (or greater) row and/or column than the previous child.true

SparkWindow

SparkWindow now has the same look and feel as a Desktop Window in Windows 10. The About button has been removed. I was able to add the blur behind option (blurred glass effect) to the Window based on the excellent tip from the blog article by Rafael Rivera - Adding the "Aero Glass" blur to your Windows 10 apps.​

NVM#, an app which I recently released, uses SparkWindow. So does the WPFSparkClient which shows the examples of the controls in WPFSpark. Both of these apps show how a SplitViewMenu can be used in a WPF application. (SplitView Control does not exist in WPF!)

Important Note: Whenever you instantiate a SparkWindow programatically, ensure that you set the properties AllowTransparency=true and WindowStyle=None before calling the ShowDialog() method. Otherwise it would throw an exception.

Three new Dependency Properties have also been added - TitleImage, TitleImageMargin, TitleMargin.

Dependency PropertyTypeDescriptionDefault Value
TitleImageUIElementGets or sets the UIElement (usually an Image) to be displayed in the TitleBar of the Window.null
TitleImageMarginThicknessGets or sets the Margin of the TitleImage.0
TitleMarginThicknessGets or sets the Margin of the Title text in the Title Bar.0

Update

SparkWindow now supports resizing. Make sure you set the ResizeMode property to CanResize. This is set in the default SparkWindow template. This allows the SparkWindow to be resized by dragging the edges or the corners.

FluidPivotPanel

PivotHeaderControl

In order to prevent a Pivot Header from being selected by the user, you can set the IsEnabled property to False. Also a new Dependency Property DisabledForeground has been added to define the foreground of the PivotHeader when it is in disabled state.

Dependency PropertyTypeDescriptionDefault Value
DisabledForegroundBrushGets or sets the Foreground of the PivotHeaderControl when it is in disabled stateBlack

PivotPanel

A new API SelectHeaderByName has been added which allows you to select a PivotHeaderControl via code. It takes the name of the PivotHeaderControl as argument.

FluidProgressBar

No changes have been made. The control should work in the same way as it did in WPFSpark v1.1.

FluidStatusBar

I have added a Dependency Property SyncLatest. When it is set to True, only the latest message will be displayed. The older messages which have not been displayed yet will be discarded. When the property is set to False, the messages will be enqueued and shown one after the other.

Dependency PropertyTypeDescriptionDefault Value
SyncLatestBooleanGets or sets the property which indicates whether the display of status message is synced with the latest message. If set to true, when messages arrive, they are not enqueued to be displayed. Instead the latest one is displayed and the older ones are discarded.False

Using WPFSpark v1.2 in your code

WPFSpark v1.2.0.1 is available in NuGet. You can obtain it here. Alternatively, you can add it to your project from Visual Studio using the Manage NuGet Packages option (Just right click on your project in the Solution Explorer and click on Manage NuGet Packages).

If you are interested in getting your hands dirty with code, you can access the WPFSpark source code in GitHub. I have moved the code from CodePlex to GitHub as I feel it is easier to manage your code in GitHub. Also the code is available under MIT License.

History

  • 26-February-2016: Added Resize feature to SparkWindow
  • 08-December-2015: WPFSpark v1.2.0.2 released
  • 01-December-2015: WPFSpark v1.2.0.1 released

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Ratish Philip
Software Developer
United States United States
An individual with more than a decade of experience in desktop computing and mobile app development primarily on the Microsoft platform. He loves programming in C#, WPF & XAML related technologies.
Current interests include web application development, developing rich user experiences across various platforms and exploring his creative side.

Ratish's personal blog: wpfspark.wordpress.com

You may also be interested in...

Comments and Discussions

 
QuestionUsing RDLC in WPFSpark created window? Pin
RaviKant Hudda30-Mar-17 9:52
professionalRaviKant Hudda30-Mar-17 9:52 
QuestionToggleSwitch accent color Pin
Member 124330082-Apr-16 20:21
memberMember 124330082-Apr-16 20:21 
AnswerRe: ToggleSwitch accent color Pin
oVasserman3-Apr-16 6:12
memberoVasserman3-Apr-16 6:12 
GeneralRe: ToggleSwitch accent color Pin
Ratish Philip4-Apr-16 6:16
memberRatish Philip4-Apr-16 6:16 
GeneralRe: ToggleSwitch accent color Pin
Ratish Philip6-Apr-16 13:03
memberRatish Philip6-Apr-16 13:03 
Questiongithub version Pin
Member 1240232422-Mar-16 9:43
memberMember 1240232422-Mar-16 9:43 
AnswerRe: github version Pin
Ratish Philip4-Apr-16 8:27
memberRatish Philip4-Apr-16 8:27 
AnswerRe: github version Pin
Ratish Philip6-Apr-16 13:04
memberRatish Philip6-Apr-16 13:04 
QuestionToggleSwitch change size Pin
Member 1239890121-Mar-16 10:47
memberMember 1239890121-Mar-16 10:47 
AnswerRe: ToggleSwitch change size Pin
Ratish Philip21-Mar-16 16:17
memberRatish Philip21-Mar-16 16:17 
GeneralRe: ToggleSwitch change size Pin
Member 1239890122-Mar-16 3:32
memberMember 1239890122-Mar-16 3:32 
QuestionIs it possible to have the drag occur when the mouse has moved a small amount instead of straight away? Pin
Member 1124467416-Mar-16 8:19
memberMember 1124467416-Mar-16 8:19 
AnswerRe: Is it possible to have the drag occur when the mouse has moved a small amount instead of straight away? Pin
Ratish Philip16-Mar-16 9:53
memberRatish Philip16-Mar-16 9:53 
GeneralRe: Is it possible to have the drag occur when the mouse has moved a small amount instead of straight away? Pin
Member 1124467417-Mar-16 1:36
memberMember 1124467417-Mar-16 1:36 
GeneralRe: Is it possible to have the drag occur when the mouse has moved a small amount instead of straight away? Pin
Ratish Philip17-Mar-16 6:56
memberRatish Philip17-Mar-16 6:56 
QuestionIs the demo project source available to download anywhere? Pin
Member 1124467415-Mar-16 6:00
memberMember 1124467415-Mar-16 6:00 
AnswerRe: Is the demo project source available to download anywhere? Pin
Ratish Philip15-Mar-16 13:10
memberRatish Philip15-Mar-16 13:10 
GeneralRe: Is the demo project source available to download anywhere? Pin
Member 1124467416-Mar-16 1:12
memberMember 1124467416-Mar-16 1:12 
GeneralRe: Is the demo project source available to download anywhere? Pin
Member 1124467416-Mar-16 3:14
memberMember 1124467416-Mar-16 3:14 
QuestionWill not install in a blank .NET 4.6 app Pin
Member 1124467414-Mar-16 7:59
memberMember 1124467414-Mar-16 7:59 
AnswerRe: Will not install in a blank .NET 4.6 app Pin
Ratish Philip14-Mar-16 12:43
memberRatish Philip14-Mar-16 12:43 
GeneralRe: Will not install in a blank .NET 4.6 app Pin
Member 1124467415-Mar-16 2:49
memberMember 1124467415-Mar-16 2:49 
GeneralRe: Will not install in a blank .NET 4.6 app Pin
Ratish Philip15-Mar-16 13:11
memberRatish Philip15-Mar-16 13:11 
GeneralRe: Will not install in a blank .NET 4.6 app Pin
Bytes1233-Oct-16 8:21
memberBytes1233-Oct-16 8:21 
GeneralRe: Will not install in a blank .NET 4.6 app Pin
Ratish Philip2-Nov-16 4:24
memberRatish Philip2-Nov-16 4:24 
GeneralMy vote of 5 Pin
netizenk1-Mar-16 7:23
membernetizenk1-Mar-16 7:23 
GeneralRe: My vote of 5 Pin
Ratish Philip2-Mar-16 3:46
memberRatish Philip2-Mar-16 3:46 
QuestionSpark window - can resize window and Pin
BMicka7-Jan-16 6:38
memberBMicka7-Jan-16 6:38 
AnswerRe: Spark window - can resize window and Pin
Ratish Philip29-Feb-16 4:52
memberRatish Philip29-Feb-16 4:52 
QuestionNice Work again! Pin
Bullimann3-Jan-16 18:38
memberBullimann3-Jan-16 18:38 
AnswerRe: Nice Work again! Pin
Ratish Philip4-Jan-16 6:41
memberRatish Philip4-Jan-16 6:41 
PraiseThank you! Pin
webmaster4425-Dec-15 2:43
memberwebmaster4425-Dec-15 2:43 
GeneralRe: Thank you! Pin
Ratish Philip5-Dec-15 4:11
memberRatish Philip5-Dec-15 4:11 
QuestionWhat is this? Pin
_Reinhard4-Dec-15 22:27
member_Reinhard4-Dec-15 22:27 
AnswerRe: What is this? Pin
Ratish Philip5-Dec-15 0:08
memberRatish Philip5-Dec-15 0:08 
GeneralRe: What is this? Pin
_Reinhard28-Dec-15 23:00
member_Reinhard28-Dec-15 23:00 
GeneralRe: What is this? Pin
Ratish Philip29-Dec-15 6:52
memberRatish Philip29-Dec-15 6:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170915.1 | Last Updated 15 Mar 2016
Article Copyright 2015 by Ratish Philip
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid