Archive for the ‘WPF’ category
String formatting in WPF and Silverlight
If you’re building controls or applications that display numbers and dates, you’re going to want to have a good understanding of how to format them nicely. In WPF and Silverlight, this is achieved using the static String.Format method which has a few overloads. The method overload we’ll be looking at takes in a string and an object as the parameters. The string parameter is a format string which will be used to format the given object. The object is whatever we want to convert to a string such as a double or a DateTime. In this blog post we will look at just a few of the many format strings provided by WPF and Silverlight for formating doubles and DateTimes. The general structure of a format string is: “{0:*}” where the * is replaced with the format string itself.
C# String format for double
Most format strings for double values are comprised of some numbers or symbols followed by a decimal point followed by some more numbers or symbols. The most common string format for formatting a double value is to specify the number of decimal places. As seen in the examples below, the number of following zeros define the exact number of decimal places to display. The number of “#” symbols can be used to define a maximum number of decimal places while only displaying digits if they are not zero. The last example below shows how “0.0#” can be used to specify that at least one decimal place is always shown, but only a maximum of two decimal places.
// exactly two decimal places String.Format("{0:0.00}", 123.4567); // "123.46" String.Format("{0:0.00}", 123.4); // "123.40" String.Format("{0:0.00}", 123.0); // "123.00" // at most two decimal places String.Format("{0:0.##}", 123.4567); // "123.46" String.Format("{0:0.##}", 123.4); // "123.4" String.Format("{0:0.##}", 123.0); // "123" // one or two decimal places String.Format("{0:0.0#}", 123.4567); // "123.46" String.Format("{0:0.0#}", 123.4); // "123.4" String.Format("{0:0.0#}", 123.0); // "123.0"
C# String format for DateTime
Format strings for DateTime objects are built up as a sequence of grouped letters. Each letter targets a particular part of the DateTime such as the year, day or hour. The number of letters in each group defines how that part should be formatted. Below is a list of some of the letters and the results of applying them to a DateTime.
DateTime dt = new DateTime(2008, 3, 9, 16, 5, 7, 0); String.Format("{0:y yy yyy yyyy}", dt); // "8 08 008 2008" year String.Format("{0:M MM MMM MMMM}", dt); // "3 03 Mar March" month String.Format("{0:d dd ddd dddd}", dt); // "9 09 Sun Sunday" day String.Format("{0:h hh H HH}", dt); // "4 04 16 16" hour 12/24 String.Format("{0:m mm}", dt); // "5 05" minute String.Format("{0:s ss}", dt); // "7 07" second String.Format("{0:t tt}", dt); // "P PM" AM or PM
By using any combination of these letter groups within a format string, you can display a DateTime in any possible way you need. Between each letter group, you may also want to include a symbol such as a comma, colon or slash. The slash and colon symbols are special characters known as the date separator and time separator respectively. One thing to keep in mind is that the date and time separator characters may be displayed differently depending on the current culture of the application. Month and day names will also be displayed in different languages based on the culture.
// DateTime format examples String.Format("{0:MM/dd/yy}", dt); // "03/09/08" String.Format("{0:dddd, MMMM d, yyyy}", dt); // "Sunday, March 9, 2008" String.Format("{0:d/M/yyyy HH:mm:ss}", dt); // "9/3/2008 16:05:07"
Format strings in XAML
If you ever come across a situation where you need to set a property of an object in XAML to be a format string, you may notice a small problem. Format strings such as the ones described in this blog post start and end with the curly bracket symbols. So the following code will fail to compile because the curly bracket is a special character which XAML will interpret in its own way rather than using it as a string.
<MyFormattingObject FormatString="{0:0.0}" />To get around this issue, all we need to do is place an empty pair of curly brackets before the format string to tell XAML to interpret it as a string value.
<MyFormattingObject FormatString="{}{0:0.0}" />More information
For a more extensive list of format string tips and tricks, you can follow this link to find DateTime formats, and check here to find string formats for doubles.
WPF Elements: How to build a multi-scheduler
One of the controls you’ll find in Mindscape WPF Elements is the Scheduler which allows users to create, edit and manage their appointments. A single scheduler control can only display appointments for a single person. In this blog post we look at how to use some of the new parts that we provide to build up your own scheduler that can display schedules for different people simultaneously. This will be similar to what Microsoft Outlook 2010 provides as seen here:
By downloading the latest nightly build of WPF Elements, you’ll see there are some new controls at your disposal. The TimeOfDayBar is used to display each hour of the day in a vertical arrangement. The DaySchedule control displays appointments for a single day, and the DayScheduleSummary control displays appointments that are 24 hours or longer. The DaySchedule and DayScheduleSummary have their own properties for setting the current date and the schedule that they display. Each of these controls can be used by themselves allowing you to build them up in what ever arrangement you like. For this project, we want to display 3 different schedules side by side. Each schedule will be made up of the following parts: A header that displays a title and the current day, a DayScheduleSummary control and a DaySchedule control.
Step 1
The first thing that we need to do is build our own control that bundles these parts together. This will make them easier to use and style. I’ve called this the DayViewControl and it contains the following dependency properties:
- Schedule: used to set the schedule that both the DaySchedule and DayScheduleSummary controls display.
- Date: used to specify which day is being displayed.
- Title: used to give each schedule its own name.
- VerticalOffset: used to synchronize all the scroll bars together.
Step 2
Next we create a style for this custom control which colors and arranges all the parts however we like. This style also includes the DaySchedule and DayScheduleSummary controls and sets some of their properties as seen below.
<ms:DayScheduleSummary Schedule="{Binding Schedule, RelativeSource={RelativeSource TemplatedParent}}" Grid.Row="1" Date="{Binding Date, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" Name="PART_DayScheduleSummary" /> <ms:DaySchedule Grid.Row="2" Schedule="{Binding Schedule, RelativeSource={RelativeSource TemplatedParent}}" Date="{Binding Date, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" VerticalOffset="{Binding VerticalOffset, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Name="PART_DaySchedule" />
Here you can see we are binding the schedule and date properties of both these controls to the schedule and date of the DayViewControl. The binding for the date property is a two way binding because some of the features of the DaySchedule control can change the date internally. We are also binding the VerticalOffset property of the DaySchedule which aids in synchronizing the scroll bars across all the schedules.
Step 3
Within the application window, we can now place 3 instances of our DayViewControl side by side. To the left of these, we can place a TimeOfDayBar, and to the right will be a scroll bar. This arrangement can be seen in the following xaml:
<ms:TimeOfDayBar Margin="0,125,0,4" VerticalOffset="{Binding VerticalOffset, Mode=TwoWay, ElementName=Calendar1}" Name="TimeOfDayBar" /> <local:DayViewControl Style="{StaticResource DayViewControlStyle}" x:Name="Calendar1" Grid.Column="1" BorderBrush="#9CBF8B" Background="#C1D8B7" Margin="0,0,6,0" Title="Ratchet" DateChanged="Calendar1_DateChanged" GotFocus="Calendar_GotFocus" /> <local:DayViewControl Style="{StaticResource DayViewControlStyle}" x:Name="Calendar2" Grid.Column="2" Margin="3,0,3,0" BorderBrush="#D195AA" Background="#E1BCC9" Date="{Binding Date, ElementName=Calendar1, Mode=TwoWay}" VerticalOffset="{Binding VerticalOffset, Mode=TwoWay, ElementName=Calendar1}" Title="Clank" GotFocus="Calendar_GotFocus" /> <local:DayViewControl Style="{StaticResource DayViewControlStyle}" x:Name="Calendar3" Grid.Column="3" BorderBrush="#8C8CD7" Margin="6,0,0,0" Background="#AFAFE4" Date="{Binding Date, ElementName=Calendar1, Mode=TwoWay}" VerticalOffset="{Binding VerticalOffset, Mode=TwoWay, ElementName=Calendar1}" Title="Dr. Nefarious" GotFocus="Calendar_GotFocus" /> <ScrollBar Maximum="{Binding ActualHeight, Converter={StaticResource ScrollBarMaximum}, RelativeSource={RelativeSource Self}}" SmallChange="30" LargeChange="30" ViewportSize="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" Grid.Column="4" Value="{Binding VerticalOffset, Mode=TwoWay, ElementName=Calendar1}" Orientation="Vertical" Margin="0,126,0,0" />
Here you will notice that we are binding all the dates and vertical offsets of the DayViewControls together. The verticalOffset of the TimeOfDayBar and the ScrollBar are also bound together so that they all move as one.
And thats it
Overall, this produces the following result:
The source code for the full project can be downloaded here. Make sure you install the latest nightly build and include a reference to your copy of WPF Elements. The project also demonstrates how to use the SchedulerNavigationBar to change the current day, and how to only allow one appointment to be selected across all the DayViewControls. Using these new controls you can create all sort of scheduler arrangements, or generalize this sample to display a variable number of schedules.
If you need advice on building your own scheduler using WPF Elements, then leave a comment on this blog, or let us know in the forum.
WPF Elements: Custom DualSlider tick mark style
The Mindscape WPF DualSlider has various features related to displaying tick marks similar to that provided by the standard WPF Slider control. The TickSpacing property allows you to set the logical distance between each of the tick marks. A pair of boolean properties called ShowTopLeftTickMarks and ShowBottomRightTickMarks specifies whether the tick marks are displayed on the top, bottom, or both edges of the slider track. Additionally, you can snap the slider thumbs to the tick marks by setting the SnapToTickMarks property to true. In this blog post we look at how to make a custom DualSlider style that has different sized tick marks based on their positions.
After setting the various properties mentioned above, the DualSlider controls generates a ReadOnlyCollection of doubles that can be acquired using the TickPositions property. This is a collection of physical positions that can be used in a style to place the tick marks. The numbers in the collection represent the distance from the left side of the slider track to each individual tick mark as illustrated below.
To style the tick marks, we can use the tick positions collection as the items source of an ItemsControl. Then we template each number to be a Border that only renders as a line on its right hand edge. The width of this border is a binding to the number itself which places the ‘tick mark’ in the correct place. Now, in order for us to render each tick mark with a different height, we start by making a class to represent an individual tick mark. Tick marks will need to know their position as well as their size which gives us the following class.
public class TickMark { public double Position { get; set; } public double Size { get; set; } }
Instead of filling an ItemsControl with a collection of positions, we now want to give it a collection of TickMark objects. This is easily achieved using a custom converter that will take the collection of positions and create instances of our TickMark objects. Within this converter, we will iterate through each of the positions and create a TickMark using the respective position. The size of each TickMark will be based on the index of the current position. Part of this converter class can be seen below.
// Size properties: public int Size0 { get; set; } ... public int Size9 { get; set; } // Convert method: public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { ReadOnlyCollection<double> positions = (ReadOnlyCollection<double>)value; IList<TickMark> tickMarks = new List<TickMark>(); int count = 0; foreach (double d in positions) { double size = GetSize(count % 10); TickMark tickMark = new TickMark() { Position = d, Size = size }; tickMarks.Add(tickMark); count++; } return tickMarks; } // Returns the size of a tick mark for the given modular interval. private int GetSize(int remainder) { switch (remainder) { case 0: return Size0; ... case 9: return Size9; } return 0; }
In the Convert method we use the ‘count’ variable to keep track of what index we are at within the loop. We perform the modular operation on this variable and use the result to select the size of the TickMark. The converter has 10 properties that will let us set the size to be given to each TickMark based on their modular index. This converter can be used in xaml as follows.
<local:TickMarkListConverter x:Key="TickMarkListConverter" Size0="9" Size5="6" /> <DataTemplate x:Key="HorizontalTickTemplate"> <Border BorderThickness="0,0,1,0" BorderBrush="Black" Height="{Binding Size}" MinWidth="1" Width="{Binding Position}" HorizontalAlignment="Left" VerticalAlignment="Top" /> </DataTemplate> <Style x:Key="HorizontalTickListStyle" TargetType="ItemsControl"> <Setter Property="ItemTemplate" Value="{StaticResource HorizontalTickTemplate}" /> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <Grid /> </ItemsPanelTemplate> </Setter.Value> </Setter> </Style>
When creating a DualSlider template, we can use an ItemsControl and set its ItemsSource to be a binding to the DualSlider.TickPositions property using the converter. The HorizontalTickTemplate as seen above uses the TickMark.Size property to set its height. Combining this with custom slider thumb and track styles can achieve results such as this:
Using this technique you can create all sorts of DualSlider styles involving tick marks with varying sizes or colors based on the requirements of your applications. A sample including all the source code for creating a custom DualSlider style in this way can be downloaded here. Let us know if you need help with styling any of the controls in WPF Elements by leaving a comment on this blog post or letting us know in the forum.
Click here to download the trial of WPF Elements.
WPF Elements 3.0 – Important notice for WPF customers
In the next couple of weeks we will be shipping WPF Elements 3.0, it will be the largest shake up to our WPF product line up to date and is great news for all our WPF Elements, WPF Property Grid and WPF Themes customers. Personally, I can’t wait to see this update come out and see some of the great applications that people will build with all the upgraded offering! :-)
Some important notes about the new release that all WPF customers should be aware of:
WPF Property Grid
We will be merging our WPF Property Grid control into the WPF Elements family. It will no longer be a stand alone product to purchase from our store. It’s interesting and a little sad to see it go as its own standalone product as it was Mindscape’s second product that was released to market but it’s also an important step in continuing maturity of our WPF offering.
What does this mean for existing customers? If you own the WPF Property Grid product you will automatically be migrated to owning WPF Elements 3.0 as part of your active subscription for free.
WPF Themes
We released a WPF Themes product that included 5 themes for all the built in WPF controls. We’ve decided that this would be better bundled up with WPF Elements 3.0 as well and will also be discontinuing the WPF Themes individual product when WPF Elements 3.0 is released.
What does this mean for existing customers? If you own the WPF Themes product you will automatically be migrated to owning WPF Elements 3.0 as part of your active subscription for free.
WPF Elements 3.0
Beyond doing the product line up tango, WPF Elements will also get a big upgrade by way of new features in existing controls and new control additions. We’ve received wonderful feedback from customers about what they would like to see added (for example, a WPF Scheduler control like the Outlook calendar) and I’m looking forward to seeing how customers make use of them.
Price changes – the call-to-action part of this post!
With WPF Elements 3.0 we will be increasing the price of the product which is why we’re making this announcement now. If you are currently evaluating any of our WPF products then it would be a very good idea to purchase a 12 month subscription today and lock in the current pricing for the next 12 months. If you already have a subscription, you may wish to extend it for another 12 months now. This will represent a substantial saving over buying the products or renewing them once WPF Elements 3.0 is released. Also, note that if you have an inactive subscription, you can still re-activate it and renew for 12 months at a reduced amount from your account page.
Existing customers can extend their subscriptions here
Cannot-wait-to-be-customers can purchase from the store here
We hope that you’ll love the new WPF Elements when we launch it later in July.
Happy coding!
WPF Diagramming 2.0 Planning

We have started work on the next generation of our popular diagramming products and wanted to get some feedback from current users. Let your minds run wild with the possibilities of what would help you build some truly stunning applications with WPF diagramming.
Some of our plans are…
When your powers combine…
Currently we’re retailing two diagramming products – WPF Flow Diagrams and WPF Star Diagrams. We’ll be merging these two into a single “WPF Diagramming” product. Developers have always been able to build far more than just Flow Diagrams and Star Diagrams with the foundation classes so we decided to simplify things and just have one tidy package for all customers. All customers who have active subscriptions to one of the diagramming products will be upgraded automatically to the joint offering of course :-) As an aside, that also means now is the best value time to purchase licenses!
Additional layout options
We’ve always included a force directed layout algorithm and a tree layout algorithm in the Star Diagrams product. We’re now working on making these work seamlessly with other diagram types as well as including several new layout algorithms to create even more attractive diagrams easily. Part of this work includes new path finding algorithms as well, so once the nodes are laid out nicely, you can control what routing algorithm is used to draw the connections between nodes.
More samples
Diagramming is a large domain to be working in and that means creating custom diagrams is not always as easy as you might hope. To help improve the situation for users, we’re planning to ship more samples that provide additional detail on how to achieve certain diagram types, work with custom nodes, configure layouts and path finding etc.
A whole bunch more
Obviously we’re including a slew of smaller feature enhancements and improvements, but what’s most important to us is that we get your feedback on what you would like to see. We’ve had solid feedback since we launched these products which has helped in the incremental improvements, and as we’re actively investing in 2.0 it’s important to hear your latest requests :-)
Never used our diagramming products? Check out WPF Flow Diagrams or WPF Star Diagrams.
Categories
BrainDump (1)
Community Code (4)
Events (16)
F# (14)
General (53)
Lab Samples (2)
LightSpeed (268)
MegaPack (8)
News (71)
NHibernate Designer (26)
Nightly news (52)
Phone Elements (24)
Products (87)
Projects (5)
Screencast (6)
SharePoint (3)
Silverlight (14)
Silverlight Elements (66)
SimpleDB Management Tools (20)
Visual Studio (9)
VS File Explorer (7)
Web Workbench (39)
WPF (44)
WPF Diagrams (57)
WPF Elements (110)
WPF Property Grid (32)


Tagged as

Posted by Jason on 31 August 2010 





