Archive for the ‘IDEs’ Category.

How to create a sphere in Expression Design

Expression Design makes creating a sphere quite easy. Below is a blue sphere with a shadow that was quite simple to make and that you can make by following this short post.

What you will learn

  • Using the ellipse tool
  • Gradient and basic manipulation and movement of the gradient
  • One possible way to create a shadow

Step 1 – Create a new Expression Design document

  1. Open Expression Design and click File | New.
  2. Name the file BlueSphere.design (or whatever name you would like).
    Note: I used a custom width and height of 250 x 125, and left the resolution at 96.
  3. Click OK.

Step 2 – Create the sphere

  1. Select the Ellipse tool from the ToolBox (which is on the left by default but you can move it wherever you want).
    Note: If you cannot find it, try pressing “L” as that is the shortcut key.
  2. Draw a circle on the screen while holding down the shift key(the shift key is what tells Expression Design that you are looking for a perfect circle and not an ellipse).
    Note: The width and height of my circle was 83.25 x 83.25.
  3. With the circle selected, go to the properties tab.
  4. Under Appearance, click the Fill tab.
    Note: Hold your cursor over the tab and it will tell you which tab is the Fill tab and which is the Stroke tab.
  5. Change the color to blue for now. We will apply gradient in the next step.
  6. Click the Stroke tab.
  7. Under the Stroke tab and all the way under the color picker, look for a drop down menu. (By default this menu has an image of a black line but can have many options.)
  8. Change it to No Stroke.
  9. Change the Stroke Width to 0 px.

Step 3 – Create the gradient effect

The gradient effect is what makes a circle on a screen look like a sphere.  It is what makes the circle appear to fade from white to dark blue.

  1. Make sure the circle is selected and go to the Properties tab.
  2. Under Appearance, click the Fill tab.
  3. Select the Gradient option.
    Note: It is the bottom left of the four boxes just left of the color boxes. Once you click this, you will have a gradient bar.
  4. To the right of the gradient bar, there are two gradient options: Linear Gradient, Radial Gradient. Choose Radial Gradient.
  5. On the gradient bar, you should see two markers (squares with a triangle on top).  Click the left marker and set the color to white.
  6. Click the right marker and set the color to blue.
    Note: I used color #153FC4.
  7. Just below the Linear Gradient, Radial Gradient option, there is a drop down that allows you to “Move, scale, rotate or skew the fill of the object”. Click it.
  8. Change X and Y to 12 px.
    Note: This moves the center of the gradient up and to the right, leaving a part of the sphere on the bottom left without a gradient.
  9. Change Width and Height to 135%.
    Note: This makes the gradient area larger fixing that the part on the bottom left that was left without the gradient when we moved the gradient up and to the left.

Step 5 – Create the shadow

In case you don’t want a shadow, this is a separate step you can choose to do if you want.

  1. Select the Ellipse tool from the ToolBox.
    Note: Remeber, try pressing “L” as it is the shortcut key.
  2. Draw an ellipse on the screen that is a little more than twice as wide as it is tall.
    Note: I created one that is 40×90.  You can see the size on the bottom of the Expression Design screen.
  3. Change the Fill to black.
  4. Under Effects, click the “fx” drop down button and choose Effects | Gaussian Blur.
  5. Set the Radius to .5.
  6. Set the Opacity to 70%.
  7. Now turn the shadow -2.7 degrees.  You can either grab a corner of the selection when the shadow is selected or you can enter this into the the Rotation Angle option at the bottom of the Expression Design window.
  8. Right-click the shadow and choose Arrange | Send to back.
  9. Place the shadow under the sphere where it looks most natural.

Click the Sphere to download a zip file containing: BlueSphere.design, a BlueSphere.png and a BlueSphere.xaml.

 

Download

 

 

Expression Studio Training Videos – A check list of videos from Expression.Microsoft.com

There are a lot of free training videos at the Expression 4 web site. However, this web site has two problems:

  1. The videos aren’t necessarily in order.
  2. There is not defined method to track your learning progress as you watch them.

Well, now it is easy. Just copy and paste this page, or easier, download this Excel document:

Expression Training Videos.xls

You can now track you progress as you self-train and go through the Expression 4 training videos.

Training Subjects



Expression Studio

Introducing Expression 4 (eight videos)
Completed Introduction Videos
Introduction to Expression Studio Ultimate
Introduction to Expression Web
Introduction to Expression Blend
Introduction to SketchFlow, a feature of Expression Studio Ultimate
Introduction to Expression Encoder Pro
Expression Web Demo Overview
Expression Blend and SketchFlow Demo Overview
Expression Encoder Pro Demo Overview
Getting Started with Silverlight – For Designers (eleven video series)
Completed Beginner Videos
What is Silverlight? An Overview
Understanding and Working with XAML Code in Expression Blend
Creating Vector-Based Artwork with Expression Design
Applying Color and Effects to Projects using Expression Design
Organizing Your Project using Layout Containers in Expression Blend
Editing the Appearance of Your Project Items using Expression Blend
Exploring the Objects and Timeline Task Pane in Expression Blend
Customizing Silverlight Video Players using Expression Blend
Optimizing Video for Silverlight Playback using Expression Encoder
Adding Interactivity to Silverlight Projects using Expression Blend
Publishing Silverlight Projects to the Web using Expression Blend
Getting Started with Standards-Based Design (ten video series)
Completed Training
Understanding the Benefits of Standards-Based Design with Expression Web
Styling Text using CSS with Expression Web
Understanding CSS Pseudo Classes for Styling Links using CSS with Expression Web
Understanding CSS Margins and Padding with Expression Web
Using CSS Positioning for Layout with Expression Web
Adding Background Images Using CSS with Expression Web
Using CSS Floats to Create Flexible Page Layouts with Expression Web
Clearing CSS Floats with Expression Web
Adding JavaSript to Your Site with Expression Web
Using External CSS Stylesheets with Expression Web



Prototyping

Additional Expression Blend Training Videos
Download the assets, step-by-step guide, and video package (127MB)
Completed Training
Introducing SketchFlow with Expression Blend 3
Adding Navigation Screens in SketchFlow with Expression Blend 3
Building Basic Layout in SketchFlow with Expression Blend 3
Using SketchStyle Controls to Enhance a SketchFlow Layout with Expression Blend 3
Working with Components in a SketchFlow Project with Expression Blend 3
Adding Navigation to Buttons in SketchFlow with Expression Blend 3
Working with States in SketchFlow with Expression Blend 3
Working with the SketchFlow Animation Panel with Expression Blend 3
Working with Behaviors in SketchFlow with Expression Blend 3
Using Sample Data in SketchFlow with Expression Blend 3
Exporting your SketchFlow project with Expression Blend 3
Adding Feedback and Annotations in the SketchFlow Player with Expression Blend 3


Additional Videos


Additional Expression Blend Training Videos
Completed Training
Displaying Dynamic Content in Silverlight using Expression Blend
Understanding and Managing Silverlight Resources with Expression Blend
Making Silverlight Objects Appear Transparent over HTML using Expression Blend
Creating a Template for a ScrollBar with Expression Blend
Customizing an Expression Encoder Template using Expression Blend
Creating Animated XAML Overlays for Expression Encoder using Expression Blend and Design
Customizing a Silverlight Template with Expression Blend
Customizing the Look of a Radio Button in Expression Blend
Customizing the Look of a Listbox in Expression Blend
Creating a Calculator with Expression Blend
Using Runtime Storyboarding in Expression Blend
Creating User Controls in Expression Blend
Reusing and Customizing User Controls in Expression Blend
Making a Slider Control in Expression Blend
Exploring XAML Layout Controls in Expression Blend
Using the Breadcrumb Trail in Expression Blend
Using Vertex Animation with Expression Blend
Using the Border Control in Expression Blend
Using the GridLayout Panel in Expression Blend
Using the Layout Stack Panel in Expression Blend
Using the Binding Scrollbar in Expression Blend
Creating Visual Transitions in Expression Blend
Use an In-State Animation To Make a Silverlight 2 Button Pulse While Focused
Customize The Check Mark In a Silverlight 2 CheckBox
Add States to a UserControl for Silverlight 2
Create Custom Buttons for Silverlight 2
Create and Edit Clipping Paths in Blend
Use the Key Spline Editor in Blend
Create the Wet Floor Effect in Expression Blend
Customize Expression Media Silverlight Templates Using Blend
Working with 3D Cameras in Expression Blend
Working With 3D Materials in Expression Blend
Importing and Manipulating 3D Objects in Expression Blend
Create User Controls in Expression Blend
Working With Clipping Paths in Expression Blend
Using an ObjectDataSource in Expression Blend
Creating a Control Template in Expression Blend
Introduction to Styles
Using Expression Design to Generate XAML Resources for Expression Blend
Motion Paths
Sharing Styles Among Heterogeneous Elements
Basic Animation
Timeline Interpolation
Working with the Grid Panel
Adding Video
Creating and Using an XMLDataSource
Create Data Templates
Creating and Using Brush Resources in Expression Blend
Introducing Blend and Working with Control Editing
Using Databinding with External Data
3D Animation and Event Triggers
Databinding to Control Properties
Designer and Developer Collaboration and Additional Demos



Beehive Game

Additional Expression Blend Training Videos
Download the assets, step-by-step guide, and video package (104 MB)
Completed Training
Organizing and Importing Assets into Expression Blend 3
Creating the BeeHive Game Interface Using Expression Blend 3
Understanding Layout Containers with Expression Blend 3
Creating a User Control with Expression Blend 3
Adding and Applying Behaviors with Expression Blend 3
Adding Game Walls and Creating Animation with Expression Blend 3
Animating Controls with the Visual State Manager with Expression Blend 3
Working with Text and Embedding Fonts with Expression Blend 3
Adding Audio Resources to a Silverlight Game with Expression Blend 3
Publishing and Testing Your Silverlight Game with Expression Blend 3

Well, once you have gone through all these videos you can probably call yourself trained in Application Design using Expression Studio, SilverLight and WPF.

With these skills expect to make between 40k (0-1 years experience) and 80k (5+ years experience).

How to disable row selection in a WPF DataGrid?

Disabling row selection in the WPF DataGrid included in .NET Framework 4 is not really easy. It is extremely difficult to do, unless you have the right tools and know exactly how to do it.

But all the difficulty is in figuring out how to do it. Once you know how to do it, the steps are quite easy to perform.

First, you basically have to use a copy of the default DataGrid style.  However, the easiest way to get a copy of the default DataGrid style is using Expression Blend.

Step 1 – Create a copy of the DataGrid’s default style

I used Expression Blend and .NET 4 to do this first step. Visual Studio 2010 doesn’t have this feature.  However, you don’t need Expression Blend because you can just copy the default style right here from this post.

(This step is a replica of the steps I posted earlier here:
How to create a copy of a control’s default style?)

  1. Open Expression Blend.
  2. Create a new WPF project. (I just used a temp project as I am coding in Visual Studio.)
  3. Add a DataGrid to your MainWindow.xaml.
  4. Right-click on the DataGrid and choose Edit Template | Edit a Copy.
  5. On the Create Style Resource page, click the “New…” button near the bottom right, just to the right of the Resource dictionary option.
  6. In the New Item window, provide a name, such as ResourceDictionaryDataGridSelectDisabled.xaml.
  7. Click OK to create the file and to return the Create Style Resource page.
  8. Make sure Resource dictionary is selected (it should be) and click OK.

You have now created a copy of the DataGrid’s default style as a Resource Dictionary file.

Note: Now that you have the DataGrid’s default style in a file, you can copy it to the project you are really working on.  I am not going to walk you through this.

Step 2 – Edit the DataGrid Style

On line 66, there is an ItemsPresenter object.  Set IsHitTestVisible="False" on this line as shown below. This is the only edit I have done.

Note: Notice I did not add an x:Key so that it will become the default style for any object that has access to this resource dictionary.

<ResourceDictionary
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	>
	<Style TargetType="{x:Type DataGrid}">
		<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
		<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
		<Setter Property="BorderBrush" Value="#FF688CAF"/>
		<Setter Property="BorderThickness" Value="1"/>
		<Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
		<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
		<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
		<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="{x:Type DataGrid}">
					<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
						Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
						<ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
							<ScrollViewer.Template>
								<ControlTemplate TargetType="{x:Type ScrollViewer}">
									<Grid>
										<Grid.ColumnDefinitions>
											<ColumnDefinition Width="Auto"/>
											<ColumnDefinition Width="*"/>
											<ColumnDefinition Width="Auto"/>
										</Grid.ColumnDefinitions>
										<Grid.RowDefinitions>
											<RowDefinition Height="Auto"/>
											<RowDefinition Height="*"/>
											<RowDefinition Height="Auto"/>
										</Grid.RowDefinitions>
										<Button Command="{x:Static DataGrid.SelectAllCommand}" Focusable="false"
											Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle,
													TypeInTargetAssembly={x:Type DataGrid}}}"
											Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All},
														 Converter={x:Static DataGrid.HeadersVisibilityConverter},
														 RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
											Width="{Binding CellsPanelHorizontalOffset,
													RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
										<DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1"
											Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column},
														 Converter={x:Static DataGrid.HeadersVisibilityConverter},
														 RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
										<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
											CanContentScroll="{TemplateBinding CanContentScroll}" Grid.ColumnSpan="2" Grid.Row="1"/>
										<ScrollBar x:Name="PART_VerticalScrollBar" Grid.Column="2" Maximum="{TemplateBinding ScrollableHeight}"
											Orientation="Vertical" Grid.Row="1"
											Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
											Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
											ViewportSize="{TemplateBinding ViewportHeight}"/>
										<Grid Grid.Column="1" Grid.Row="2">
											<Grid.ColumnDefinitions>
												<ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset,
																 RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
												<ColumnDefinition Width="*"/>
											</Grid.ColumnDefinitions>
											<ScrollBar x:Name="PART_HorizontalScrollBar" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}"
												Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
												Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
												ViewportSize="{TemplateBinding ViewportWidth}"/>
										</Grid>
									</Grid>
								</ControlTemplate>
							</ScrollViewer.Template>
							<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" IsHitTestVisible="False"/>
						</ScrollViewer>
					</Border>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
		<Style.Triggers>
			<Trigger Property="IsGrouping" Value="true">
				<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
			</Trigger>
		</Style.Triggers>
	</Style>
	<!-- Resource dictionary entries should be defined here. -->
</ResourceDictionary>

Step 3 – Configure the DataGrid to use the new style

Now that you have your new style in a resource dictionary (and I assume you have already added the file you created in Step 1 to your project), you can add the ResourceDictionary to the DataGrid’s object under DataGrid.Resources as shown.

<DataGrid ... />
    <DataGrid.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="ResourceDictionaryDataGridSelectDisabled.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </DataGrid.Resources>
</DataGrid>

I hope this helps you have some more success with a DataGrid from day one as it took me some time to get this working.

How to create a copy of a control’s default style?

Sometimes you need to make some advanced styling changes to a default control, such as a RadioButton, ListBox, DataGrid, Button, etc. However, you may want to keep the majority of the default style the way it is.

In Expression Blend, this is easy to do.  If you don’t have Expression Blend and you are developing in WPF, get it immediately.  There is a trial version you can test out.

Here is how to get your copy of any control’s default style.

  1. Open Expression Blend.
  2. Create a new WPF project. (It is just a temp project.)
  3. Add the default control to your MainWindow.xaml.
  4. Right-click on the control and choose Edit Template | Edit a Copy.
  5. On the Create Style Resource page, click the “New…” button near the bottom right, just to the right of the Resource dictionary option.
  6. In the New Item window, provide a name that is meaningfule.
  7. Click OK to create the file and to return the Create Style Resource page.
  8. Make sure Resource dictionary is selected (it should be) and click OK.

You have now created a copy of the default style of the control.  You now have power to manipulate the control in advanced ways.

Important! Be aware that some controls and made up of other controls, and often you have to do this for each control that your control uses.  For example, a DataGrid has many different subcomponents such as a ScrollViewer, an ItemsPresenter, Grids, etc…

WPF replacement options for an animated gif or How to make a spinner?

Option 1 – Spin an image using a Storyboard

UPDATE: Check out this more recent post: A SpinningImage control in WPF

If your animation is just a single image that moves, such as a spinner, you can use a Storyboard to spin the single image.

Here is a spinner.png file (128×128) that I made really quickly in Paint.NET.

Spinner

  1. Create a default WPF Application project in visual studio.
  2. Add the spinner.png image to the project (or use your own image).
  3. Add a Storyboard to the resources.

Here is the Xaml.

<Window x:Class="SpinAnImage.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="300">
    <Window.Resources>
        <Storyboard x:Key="Spin360" Storyboard.TargetName="Spinner" Storyboard.TargetProperty="RenderTransform.(RotateTransform.Angle)">
            <DoubleAnimation From="0" To="360" BeginTime="0:0:0" Duration="0:0:2" RepeatBehavior="Forever" />
        </Storyboard>
    </Window.Resources>
    <Grid>
        <Image Name="Spinner" Source="spinner.png" Width="128" Height="128" RenderTransformOrigin="0.5, 0.5">
            <Image.Triggers>
                <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                    <EventTrigger.Actions>
                        <BeginStoryboard Storyboard="{StaticResource Spin360}" />
                    </EventTrigger.Actions>
                </EventTrigger>
            </Image.Triggers>
            <Image.RenderTransform>
                <RotateTransform Angle="0" />
            </Image.RenderTransform>
        </Image>
    </Grid>
</Window>

Here is the simple Visual Studio 2010 project:

SpinAnImage.zip

Option 2 – Loop through images using a Storyboard

This option is the one you would use if you have multiple images. You can create a Storyboard that loops through all of your images. If you have a gif, you can extract each image and use them.

Here is a BlackSpinner1.png file (128×128) that I made really quickly in Paint.NET. Actually I made eight versions of this image, where the section that is gray changes in each image.

Here is how you configure your project to animate through these images.

  1. Create a default WPF Application project in visual studio.
  2. Add a folder to the project called Images.
  3. Add the images you want to loop through to the Images directory.
  4. Add a Storyboard to the resources.

Here is the Xaml.

<Window x:Class="SpinUsingMultipleImages.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Spinner using multiple images" Height="300" Width="300">
    <Grid>
        <Grid.Resources>
            <Storyboard x:Key="BlackSpinnerStoryBoard">
                <ObjectAnimationUsingKeyFrames Duration="0:0:2" Storyboard.TargetProperty="Source" RepeatBehavior="Forever">
                    <DiscreteObjectKeyFrame KeyTime="0:0:0">
                        <DiscreteObjectKeyFrame.Value>
                            <BitmapImage UriSource="Images/BlackSpinner1.png"/>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame KeyTime="0:0:0.25">
                        <DiscreteObjectKeyFrame.Value>
                            <BitmapImage UriSource="Images/BlackSpinner2.png"/>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame KeyTime="0:0:0.50">
                        <DiscreteObjectKeyFrame.Value>
                            <BitmapImage UriSource="Images/BlackSpinner3.png"/>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame KeyTime="0:0:0.75">
                        <DiscreteObjectKeyFrame.Value>
                            <BitmapImage UriSource="Images/BlackSpinner4.png"/>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame KeyTime="0:0:1">
                        <DiscreteObjectKeyFrame.Value>
                            <BitmapImage UriSource="Images/BlackSpinner5.png"/>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame KeyTime="0:0:1.25">
                        <DiscreteObjectKeyFrame.Value>
                            <BitmapImage UriSource="Images/BlackSpinner6.png"/>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame KeyTime="0:0:1.50">
                        <DiscreteObjectKeyFrame.Value>
                            <BitmapImage UriSource="Images/BlackSpinner7.png"/>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame KeyTime="0:0:1.75">
                        <DiscreteObjectKeyFrame.Value>
                            <BitmapImage UriSource="Images/BlackSpinner8.png"/>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>
        </Grid.Resources>
        <Image Name="BlackSpinner">
            <Image.Triggers>
                <EventTrigger RoutedEvent="Image.Loaded">
                    <EventTrigger.Actions>
                        <BeginStoryboard Storyboard="{StaticResource BlackSpinnerStoryBoard}" />
                    </EventTrigger.Actions>
                </EventTrigger>
            </Image.Triggers>
        </Image>
    </Grid>
</Window>

Here is a sample project attached.

SpinUsingMultipleImages.zip

10 Step process for developing a new WPF application the right way using C#

It makes a difference if you do something the right way from the beginning.  Everything seems to work out so much better and takes less time over all.

Here are some basic steps that I have learned will help you do it right the first time. These steps are from my experience, mostly because I did it wrong the first few times.  These are not exact steps. They are subject to change and improve.  In fact, you might have improvements to suggest immediately when you read this. But if you are new to WPF, then reading these steps before you start and following them, will have you closer it doing it the right way the first time.  It is much more pleasant to tweak a pretty good process than it is to go in with no idea for a process and do it wrong.

Step 1 – Prepare the idea

  1. Some one has an idea
  2. Determine the minimal features for release 1.
  3. Determine the minimal features for release 2.
    1. Alter minimal features for release 1 if it makes sense to do so.
  4. Determine the minimal features for release 3.
    1. Alter minimal features for release 1 and 2 if it makes sense to do so.

Step 2 – Design the Application’s back end business logic (simultaneous to Step 3)

  1. Design the backend
  2. Apply the “Keep it simple” idea to the business logic and makes changes as necessary.
  3. Apply the “Keep it secure” idea to the business logic and makes changes as necessary.
  4. Repeats steps 2 and 3 if necessary.
  5. Backend development can start now as the UI and the back end should not need to know about each other.

Step 3 – Design the UI using WPF (simultaneous to Step 2)

  1. Determine what development model should be used to separate the UI from the business logic.
    1. Model-View-ViewModel (MVVM) is the model I recommend for WPF.
    2. Gather libraries used for the model (such as common MVVM libraries that include the common ViewModelBase and RelayCommand objects)
  2. Consider using a 3rd party WPF control set will be used.  Many 3rd party companies provide WPF controls that are better and easier to use than those included by default.
    1. If you decided to use 3rd party controls, purchase or otherwise obtain the libraries for these 3rd party controls.
  3. Consider designing two WPF interfaces or skins (I will call these Views from here on out) for each screen. This will help drive the separation of the back end code from the WPF code. Also if developing two Views is not simple, it indicates a poor design.
  4. Design the interface(s) (you may be doing two Views) using SketchFlow (take time to include the libraries for the 3rd party WPF Controls in your SketchFlow project and design with them)
    1. SketchFlow allows you to design the UI, which is commonly done in paint, but instead does this in XAML, and is actually the WPF code your application will use.
  5. SketchFlow allows you to deliver the design (or both Views if you did two) as a package to the customer.
    1. Deliver it immediately and get feedback.
    2. Make changes suggested by the customer if in scope.
  6. Take time to make the XAML in SketchFlow production ready.
  7. Deliver the XAML to the customer again, to buy of that the design changes are proper.
    1. Make changes suggested by the customer if in scope.

Step 4 – Determine the delivery or install method

  1. Determine the delivery method.
  2. Determine when to develop the delivery method.
    1. The easier the application is, the longer you can wait to determine the installer or delivery method.
    2. The more complex the install or delivery method, the sooner this should be started.

Step 5 – Develop the business logic

  1. Develop the application designed in step 2.
  2. Get the application working without UI or silently. Note: Start the next step, Develop the UI, as soon as enough code is available here.

Step 6 – Develop the UI

  1. Start the UI project by copying the XAML from the SketchFlow document to your Visual Studio or Expression Blend project.
  2. Create a project for the ViewModel code and develop it to interact with the model and business logic using Binding.
  3. Remember to develop two Views for every UI screen as this will help, though not guarantee, that the the MVVM model was correctly used.

Step 7 – Consider a Macintosh version

Macintosh owns a significant market share.  Determine if this application needs to run on Macintosh as well. Sure, since we are running C# your options are limited to either rewriting in objective C and Coca, or using Mono with a MonoMac UI.  I recommend the latter.

Note: It is critical that the UI and business logic are separated to really make this successful.

  1. Completely ignore the WPF design and have Macintosh users users assist the design team in designing the new UI.  Macintosh’s have a different feel, and trying to convert the same UI is a mistake.
  2. Create the MonoMac UI project.
  3. Create a project similar to the ViewModel project in Windows, to link the UI to the business logic.

Step 8 – Consider a BSD/Linux/Unix (BLU) version

BLU (BSD/Linux/Unix) doesn’t exactly own a significant market share. However, it is still important to determine if this application needs to run on on BLU as well. Sure, since we are running C# your options are limited to either rewriting in C++, or using Mono with a GTK# or Forms UI.

  1. Completely ignore the WPF and Macintosh designs and have Linux users assist the design team in designing the new UI. Linux has a different feel, and trying to convert the same UI could be a mistake.
  2. Create the GTK# project.
  3. Create a project similar to the ViewModel project in Windows, to link the UI to the business logic.
  4. GTK# doesn’t support binding, but still keep the UI separate from the business logic as much as possible.

Step 9 – Develop the delivery method

Again, you may need to do this way sooner if the application is complex.

  1. Develop the install or delivery method.
  2. If you decided to deploy to Macintosh or BLU you may have to develop separate install or delivery methods for those platforms as well.

Step 10 – Deliver the finished Products

  1. Once finished, deliver this product.
  2. If you decided to create a Macintosh or BLU version, deliver them when ready as well.  It is OK and maybe preferred to deliver these at different times.

How to configure the WPF RadioButton's circle bullet top aligned when there are multiple lines of text?

Today I had to solve a problem that appeared quite difficult, but turned out to not be so hard if I let Expression Blend do most the work and finish it up in the XAML. I ended up having to completely recreate the default template style and then modify it.

Note: This article could also be titled: How to change the default template style of a standard control?

I had a RadioButton with text that wraps and it wasn’t displaying exactly how my team wanted. Here is the XAML.

<Window x:Class="RadioButtonTopAligned.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <RadioButton GroupName="RadioButtonList">
            <Label>
                <AccessText TextWrapping="Wrap" Text="_This is a very long radio button control line of text that should wrap." MaxWidth="300"/>
            </Label>
        </RadioButton>
    </Grid>
</Window>

The problem is that the circle bullet is center aligned like this:

Notice how the circle bullet is aligned in between the two lines of text. I need it to be top aligned like this:

Notice how the circle bullet is aligned with the top line of text. I need to get WPF to do this.

From a Visual Studio 2010 point of view, there is no easy way to do this. At first I thought it would be a simple dependency property, but it isn’t. An quick internet search led me to realize that I have to pretty much re-style the whole RadioButton. This sounds really hard and in fact, in Visual Studio, without help, it would be really hard. You would have to have the code for the default template style for the RadioButton control memorized.

Here is an forum post I found from MSDN: How do I make a RadioButton’s Bullet align top

While the post is exactly what I was looking for and has an answer, I didn’t at first grasp the answer. I wasn’t sure what was going on until one of my co-workers, Shawn, who is more skilled in Expression Blend, showed me. Now that I understand, I want to make sure the next person who finds the same forum post on MSDN can understand even easier by writing this article and adding it to the forum post.

This is where Expression Blend comes in. If you don’t have Expression Blend, don’t worry, you can still get through this article as I will include the the default style code that Expression Blend created for me right here in my post.

In Expression Blend, this is what to do.

  1. Create a blank WPF project in Expression Blend.
  2. Add a RadioButton.
  3. Right-click on the RadioButton and choose Edit Template | Edit a Copy…
  4. Click OK on the Create Style Resource window.

Here is what happens to your XAML and you can do this to the XAML in you project manually if you don’t have Expression Blend.

  1. The following reference is added to the project: PresentationFramework.Aero
  2. The same is referenced in the XAML (See line 4 of the XAML below)
  3. The default RadioButton style is copied to your XAML under the Window.Resources element.  (See lines 10-48 in the XAML below)
  4. The RadioButton is assigned the style created. (See line 51 in the XAML below)
<Window
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
	x:Class="RadioButtonTopAligned_EB.MainWindow"
	x:Name="Window"
	Title="MainWindow"
	Width="640" Height="480">

	<Window.Resources>
		<SolidColorBrush x:Key="CheckBoxStroke" Color="#8E8F8F"/>
		<Style x:Key="CheckRadioFocusVisual">
			<Setter Property="Control.Template">
				<Setter.Value>
					<ControlTemplate>
						<Rectangle Margin="14,0,0,0" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
					</ControlTemplate>
				</Setter.Value>
			</Setter>
		</Style>
		<Style x:Key="RadioButtonStyle1" TargetType="{x:Type RadioButton}">
			<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
			<Setter Property="Background" Value="#F4F4F4"/>
			<Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
			<Setter Property="BorderThickness" Value="1"/>
			<Setter Property="Template">
				<Setter.Value>
					<ControlTemplate TargetType="{x:Type RadioButton}">
						<BulletDecorator Background="Transparent">
							<BulletDecorator.Bullet>
								<Microsoft_Windows_Themes:BulletChrome BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" IsChecked="{TemplateBinding IsChecked}" IsRound="true" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"/>
							</BulletDecorator.Bullet>
							<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
						</BulletDecorator>
						<ControlTemplate.Triggers>
							<Trigger Property="HasContent" Value="true">
								<Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
								<Setter Property="Padding" Value="4,0,0,0"/>
							</Trigger>
							<Trigger Property="IsEnabled" Value="false">
								<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
							</Trigger>
						</ControlTemplate.Triggers>
					</ControlTemplate>
				</Setter.Value>
			</Setter>
		</Style>
	</Window.Resources>

	<Grid x:Name="LayoutRoot">
		<RadioButton GroupName="RadioButtonList" Style="{DynamicResource RadioButtonStyle1}">
			<Label>
				<AccessText TextWrapping="Wrap" Text="_This is a very long radio button control line of text that should wrap." MaxWidth="300"/>
			</Label>
		</RadioButton>
	</Grid>
</Window>

Now we can edit the XAML. Below is the same XAML as above with the following edits:

  1. Inside the BulletDecorator.Bullet element on line 30, create a DockPanel around the BulletChrome element.
  2. The ControlPresenter is moved to be inside the DockPanel.
  3. Add the following XAML atrributes to the BulletChrome element:
    VerticalAlignment=”Top” Margin=”0,8,0,0″ Height=”{TemplateBinding FontSize}” Width=”{TemplateBinding FontSize}”

    Note: If you change the font of the text content in the RadioButton, you should change the Margin in the style as well. I haven’t figured out how to make it always match the top line without manually tweaking it when you change the font. Also, if you don’t want the BulletChrome element to be the same size as the font, you will have to tweak Width and Height too.

<Window
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
	x:Class="RadioButtonTopAligned_EB.MainWindow"
	x:Name="Window"
	Title="MainWindow"
	Width="640" Height="480">

	<Window.Resources>
		<SolidColorBrush x:Key="CheckBoxStroke" Color="#8E8F8F"/>
		<Style x:Key="CheckRadioFocusVisual">
			<Setter Property="Control.Template">
				<Setter.Value>
					<ControlTemplate>
						<Rectangle Margin="14,0,0,0" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
					</ControlTemplate>
				</Setter.Value>
			</Setter>
		</Style>
		<Style x:Key="RadioButtonStyle1" TargetType="{x:Type RadioButton}">
			<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
			<Setter Property="Background" Value="#F4F4F4"/>
			<Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
			<Setter Property="BorderThickness" Value="1"/>
			<Setter Property="Template">
				<Setter.Value>
					<ControlTemplate TargetType="{x:Type RadioButton}">
						<BulletDecorator Background="Transparent">
							<BulletDecorator.Bullet>
								<DockPanel>
									<Microsoft_Windows_Themes:BulletChrome VerticalAlignment="Top" Margin="0,8,0,0" Height="{TemplateBinding FontSize}" Width="{TemplateBinding FontSize}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" IsChecked="{TemplateBinding IsChecked}" IsRound="true" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" />
									<ContentPresenter RecognizesAccessKey="True" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
								</DockPanel>
							</BulletDecorator.Bullet>
							</BulletDecorator>
						<ControlTemplate.Triggers>
							<Trigger Property="HasContent" Value="true">
								<Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
								<Setter Property="Padding" Value="4,0,0,0"/>
							</Trigger>
							<Trigger Property="IsEnabled" Value="false">
								<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
							</Trigger>
						</ControlTemplate.Triggers>
					</ControlTemplate>
				</Setter.Value>
			</Setter>
		</Style>
	</Window.Resources>

	<Grid x:Name="LayoutRoot">
		<RadioButton GroupName="RadioButtonList" Style="{DynamicResource RadioButtonStyle1}">
			<Label>
				<AccessText TextWrapping="Wrap" Text="_This is a very long radio button control line of text that should wrap." MaxWidth="300"/>
			</Label>
		</RadioButton>
	</Grid>
</Window>

I hope this posts clarifies how to completely recreate a template style for a default control to modify something that at first doesn’t appear modifiable.

Installing the latest version of Mono on FreeBSD or How to install and use portshaker?

Mono is basically the .NET Framework on FreeBSD or other open source platforms. This allows development in C# on FreeBSD.  C# is an extremely popular language that is not slowing down.  It’s popularity stems from that fact that this language and its features allow for much rapid development than many other languages.

The version of Mono available in the ports tree is not the latest version available. Just like FreeBSD has a release version and a development version, Mono has a release version and a development version.  The development version is so much newer that it is hard not to recommend it over the release version.

Step 1 – Install the latest ports

This is already documented here:

How to install ports on FreeBSD?

Step 2 – Install portshaker

The team at BSD# have a tool called portshaker that adds mono ports to the ports tree.  Install it as follows.

#
#
cd /usr/ports/ports-mgmt/portshaker-config
make BATCH=yes install

Step 3 – Configure portshaker

The example portshaker.conf.example is configured correctly for default configurations, so all we need to do is copy it.

# cp /usr/local/etc/portshaker.conf.example /usr/local/etc/portshaker.conf

Step 4 – Run portshaker

Yes, it is that easy.  Simply run portshaker.

# portshaker

Note: You may be prompted to merge a few files. I chose install each time.

Your ports tree is now updated by portshaker.

Step 5 – Install mono

The mono port should now be updated to the latest version.

#
#
cd /usr/ports/lang/mono
make BATCH=yes install

Mono is now installed on your system.

There is an example of building a hello world app here:

C# (Mono) on FreeBSD

Binding Visibility to a bool value in WPF

I was putting code in my ViewModel that returns Visibility but I didn’t really like that very much. If the UI is created with something other than WPF, that is really not going to work. Since I intend to do cross compile my code in Mono, which doesn’t have WPF but uses either Forms or GTK#, I have already encountered this issue. What I really want to use is bool.

The solution is IValueConverter. If you just want the code and don’t want to read this post, just scroll to the bottom and grab the

IValueConverter is part of PresentationFramework (in PresentationFramework.dll) so it isn’t available in Mono, but that is OK because you don’t instantiate it in the ViewModel, you use it in the View so it will only be used when the GUI is part of WPF. So if you are separating your View into a separate DLL, this would be included in the View DLL, that way when you compile everything else, with say a different GUI that uses GTK#, you won’t get a compiler error because PresentationFramework doesn’t exist in Mono.

BooleanToVisibilityConverter

Well, there is an object already created for you called BooleanToVisibilityConverter, but it is limited. True is converted Visibility.Visible. False is converted to Visibility.Collapsed.

Here we see a problem. Visibility has three possible values but a Boolean only has two.

Boolean Visibility
True Visible
False Collapsed
Hidden

This will cover many of the scenarios, but not all.

Here is how it would be used.

For this example, I have this Person class.

    public class Person
    {
        public Person() { }
        public String FirstName { get; set; }
        public String LastName { get; set; }
        public String Age { get; set; }
    }

Here is a simple View for this object. It has a Grid that has a Label and TextBox for each property in the Person object. It also has a CheckBox. The CheckBox gives us a easy bool value, IsChecked. This works similar to a bool property in a ViewModel.

<Window x:Class="TestBooleanToVisibilityConverter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TestBooleanToVisibilityConverter"
        Title="MainWindow"
        SizeToContent="WidthAndHeight"
        >
    <Grid Margin="20">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid Name="PersonViewGrid">
            <Grid.Resources>
                <BooleanToVisibilityConverter x:Key="BoolToVisConverter"/>
            </Grid.Resources>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Label Content="First Name:" Grid.Column="0" Grid.Row="0" />
            <TextBox Grid.Column="1" Grid.Row="0" Name="firstNameTextBox"
                     Text="{Binding Path=FirstName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" MinWidth="175" />
            <Label Content="Last Name:" Grid.Column="0" Grid.Row="1" />
            <TextBox Grid.Column="1" Grid.Row="1" Name="lastNameTextBox"
                     Text="{Binding Path=LastName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" MinWidth="175" />
            <Label Content="Age:" Grid.Column="0" Grid.Row="2"
                   Visibility="{Binding IsChecked, ElementName=ShowAgeCheckBox, Converter={StaticResource BoolToVisConverter}}"/>
            <TextBox Grid.Column="1" Grid.Row="2" Name="ageTextBox"
                     Text="{Binding Path=Age, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" MinWidth="175"
                   Visibility="{Binding IsChecked, ElementName=ShowAgeCheckBox, Converter={StaticResource BoolToVisConverter}}"/>
        </Grid>
        <Grid Grid.Row="1">
            <CheckBox Name="ShowAgeCheckBox" Content="Show Age" />
        </Grid>
    </Grid>
</Window>

I am not using MVVM for this example, but instead there is a just a single object created in the code behind for demo purposes.

using System;
using System.Windows;

namespace TestBooleanToVisibilityConverter
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent(); Person p = new Person() { FirstName = "Michael", LastName = "Michaels", Age = "33" };
            PersonViewGrid.DataContext = p;
        }

    }
}

Ok, now build the project and you will see that the Label and TextBox for Age are hidden until you check the box.

Writing your own Bool to Visibility Converter

Sometimes you may need to write you own Converter.  For example, in the above project, it is annoying how the CheckBox moves up and down in position because Visibility.Collapsed is used instead of Visibility.Hidden.  You may want to use Visibility.Hidden instead.

You can write your own Converter that returns Visibility.Hidden instead of Visibility.Collapsed.

BooleanToVisibleOrHidden.cs

using System;
using System.Windows.Data;
using System.Windows;

namespace TestBooleanToVisibilityConverter
{
    class BoolToVisibleOrHidden : IValueConverter
    {
        #region Constructors
        /// <summary>
        /// The default constructor
        /// </summary>
        public BoolToVisibleOrHidden() { }
        #endregion

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool bValue = (bool)value;
            if (bValue)
                return Visibility.Visible;
            else
                return Visibility.Hidden;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Visibility visibility = (Visibility)value;

            if (visibility == Visibility.Visible)
                return true;
            else
                return false;
        }
        #endregion
    }
}

Here we do the conversion ourselves and now we have a different conversion table.

Boolean Visibility
True Visible
Collapsed
False Hidden

Now replace the Converter object in your XAML.  We only change Line 15.

      <local:BoolToVisibleOrHidden x:Key="BoolToVisConverter"/>

This works, but it could be improved. This still leaves us having to choose between two objects.

Creating a Converter that supports a choice of Hidden or Collapsed.

Here we will provide a property that determines if we should collapse or not.

Add a property called Collapse and return the appropriate Visibility based on that property. Here is the new object. As you see, the code changes to add this feature is really just an empty bool property and an if statement that used the bool property.

using System;
using System.Windows.Data;
using System.Windows;

namespace TestBooleanToVisibilityConverter
{
    class BoolToVisibleOrHidden : IValueConverter
    {
        #region Constructors
        /// <summary>
        /// The default constructor
        /// </summary>
        public BoolToVisibleOrHidden() { }
        #endregion

        #region Properties
        public bool Collapse { get; set; }
        #endregion

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool bValue = (bool)value;
            if (bValue)
            {
                return Visibility.Visible;
            }
            else
            {
                if (Collapse)
                    return Visibility.Collapsed;
                else
                    return Visibility.Hidden;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Visibility visibility = (Visibility)value;

            if (visibility == Visibility.Visible)
                return true;
            else
                return false;
        }
        #endregion
    }
}

Now in your XAML you have the option to do nothing, which uses the bool default value false, or to set the Collapse property to true as shown below.

      <local:BoolToVisibleOrHidden x:Key="BoolToVisConverter" Collapse="True"/>

We now support either feature with the following table. We probably at this point would rename the object to BooleanToVisibilityConverter, but Microsoft already took that object name so I will leave it named as is.

Boolean Visibility
True Visible
False – Collapse=True Collapsed
False – Collapse=False Hidden

We are starting to get a little more usability from one object.

Adding the Reverse feature so False is Visible and True is Collapsed or Hidden

Lets say we want to change the CheckBox so that instead of saying “Show Age” it says “Hide Age”.

            <CheckBox Name="ShowAgeCheckBox" Content="Hide Age" />

Now we have to reverse the mapping. If Reverse=”True” we want the mapping to be like this:

Boolean Visibility
False Visible
True – Collapse=True Collapsed
True – Collapse=False Hidden

This is also quite simple. We add another bool property called Reverse. Then key of that in another if statement.

using System;
using System.Windows.Data;
using System.Windows;

namespace TestBooleanToVisibilityConverter
{
    class BoolToVisibleOrHidden : IValueConverter
    {
        #region Constructors
        /// <summary>
        /// The default constructor
        /// </summary>
        public BoolToVisibleOrHidden() { }
        #endregion

        #region Properties
        public bool Collapse { get; set; }
        public bool Reverse { get; set; }
        #endregion

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool bValue = (bool)value;

                if (bValue != Reverse)
                {
                    return Visibility.Visible;
                }
                else
                {
                    if (Collapse)
                        return Visibility.Collapsed;
                    else
                        return Visibility.Hidden;
                }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Visibility visibility = (Visibility)value;

                if (visibility == Visibility.Visible)
                    return !Reverse;
                else
                    return Reverse;
        }
        #endregion
    }
}

Now you can reverse this very easily in the XAML.

      <local:BoolToVisibleOrHidden x:Key="BoolToVisConverter" Collapse="True" Reverse="True" />

And now you have a much more full featured converter.

Additional Thoughts

I have to wonder why the developers didn’t do this originally with the BooleanToVisibilityConverter object. It is so simple. This is a perfect example of where Microsoft would benefit from Open Sourcing some of their code. A dozen people would have contributed this change by now if they had and all Microsoft would have to do is look at the submitted code, approve, and check it in.

How read the 64 bit registry from a 32 bit application or vice versa

I found out that I needed to read the 64 bit registry from a 32 bit app today.
Why you might ask?
Well, I need to get the RegisteredOrganization value from HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion and unfortunately Microsoft has a bug where the WOW6432 version of this key always says Microsoft, so a 32 bit application would always return Microsoft as the RegisteredOrganization, regardless of what the user entered when they installed the OS. This is hardly desired.
Note: This is also why all Visual Studio projects created in Windows 7 64 bit have Microsoft in the project’s Assembly Information. Change the WOW6432 version of the RegisteredOrganization and you fix this Visual Studio issue.
Well, turns out C# doesn’t have functionality until .NET 4, so prior to .NET 4, to choose the 64 bit hive when running a 32 bit app, so we have to do use a DLLImport and use RegOpenKeyEx, RegCloseKey, and RegQueryValueEx.
I don’t have this well commented, and it is not very newbie proof, but here are three different ways to do this. Hopefully you can understand one or more of these.

Example 1 – .NET 4 Example

Here is how to do this in .NET 4.
using Microsoft.Win32;

namespace Read64bitRegistryFrom32bitApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string value64 = string.Empty;
            string value32 = string.Empty;

            RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
            localKey = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
            if (localKey != null)
            {
                value64 = localKey.GetValue("RegisteredOrganization").ToString();
            }
            RegistryKey localKey32 = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32);
            localKey32 = localKey32.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
            if (localKey32 != null)
            {
                value32 = localKey32.GetValue("RegisteredOrganization").ToString();
            }
        }
    }
}

.NET 3.5 SP1 and Prior

This can also be done in .NET 3.5 and prior but it is not easy.
We have to do use a DLLImport and use RegOpenKeyEx, RegCloseKey, and RegQueryValueEx. Here are some examples.

Example 1 – A console application to read the 64 bit registry from a 32 bit application or vice versa

Here is the code in a simple one file project:
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Read64bitRegistryFrom32bitApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string value64 = GetRegKey64(RegHive.HKEY_LOCAL_MACHINE, @"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "RegisteredOrganization");
            Console.WriteLine(value64);
            string value32 = GetRegKey32(RegHive.HKEY_LOCAL_MACHINE, @"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "RegisteredOrganization");
            Console.WriteLine(value32);
        }

        public enum RegSAM
        {
            QueryValue = 0x0001,
            SetValue = 0x0002,
            CreateSubKey = 0x0004,
            EnumerateSubKeys = 0x0008,
            Notify = 0x0010,
            CreateLink = 0x0020,
            WOW64_32Key = 0x0200,
            WOW64_64Key = 0x0100,
            WOW64_Res = 0x0300,
            Read = 0x00020019,
            Write = 0x00020006,
            Execute = 0x00020019,
            AllAccess = 0x000f003f
        }

        public static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);
        public static UIntPtr HKEY_CURRENT_USER = new UIntPtr(0x80000001u);

        #region Member Variables
        #region Read 64bit Reg from 32bit app
        [DllImport("Advapi32.dll")]
        static extern uint RegOpenKeyEx(
            UIntPtr hKey,
            string lpSubKey,
            uint ulOptions,
            int samDesired,
            out int phkResult);

        [DllImport("Advapi32.dll")]
        static extern uint RegCloseKey(int hKey);

        [DllImport("advapi32.dll", EntryPoint = "RegQueryValueEx")]
        public static extern int RegQueryValueEx(
            int hKey, string lpValueName,
            int lpReserved,
            ref uint lpType,
            System.Text.StringBuilder lpData,
            ref uint lpcbData);
        #endregion
        #endregion

        #region Functions
        static public string GetRegKey64(UIntPtr inHive, String inKeyName, String inPropertyName)
        {
            return GetRegKey64(inHive, inKeyName, RegSAM.WOW64_64Key, inPropertyName);
        }

        static public string GetRegKey32(UIntPtr inHive, String inKeyName, String inPropertyName)
        {
            return GetRegKey64(inHive, inKeyName, RegSAM.WOW64_32Key, inPropertyName);
        }

        static public string GetRegKey64(UIntPtr inHive, String inKeyName, RegSAM in32or64key, String inPropertyName)
        {
            //UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002;
            int hkey = 0;

            try
            {
                uint lResult = RegOpenKeyEx(RegHive.HKEY_LOCAL_MACHINE, inKeyName, 0, (int)RegSAM.QueryValue | (int)in32or64key, out hkey);
                if (0 != lResult) return null;
                uint lpType = 0;
                uint lpcbData = 1024;
                StringBuilder AgeBuffer = new StringBuilder(1024);
                RegQueryValueEx(hkey, inPropertyName, 0, ref lpType, AgeBuffer, ref lpcbData);
                string Age = AgeBuffer.ToString();
                return Age;
            }
            finally
            {
                if (0 != hkey) RegCloseKey(hkey);
            }
        }
        #endregion
    }
}

Example 2 – A static class to read the 64 bit registry from a 32 bit application or vice versa

Or if you want this in its own separate class, here is a static class you can add to your project.
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Read64bitRegistryFrom32bitApp
{
    public enum RegSAM
    {
        QueryValue = 0x0001,
        SetValue = 0x0002,
        CreateSubKey = 0x0004,
        EnumerateSubKeys = 0x0008,
        Notify = 0x0010,
        CreateLink = 0x0020,
        WOW64_32Key = 0x0200,
        WOW64_64Key = 0x0100,
        WOW64_Res = 0x0300,
        Read = 0x00020019,
        Write = 0x00020006,
        Execute = 0x00020019,
        AllAccess = 0x000f003f
    }

    public static class RegHive
    {
        public static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);
        public static UIntPtr HKEY_CURRENT_USER = new UIntPtr(0x80000001u);
    }

    public static class RegistryWOW6432
    {
        #region Member Variables
        #region Read 64bit Reg from 32bit app
        [DllImport("Advapi32.dll")]
        static extern uint RegOpenKeyEx(
            UIntPtr hKey,
            string lpSubKey,
            uint ulOptions,
            int samDesired,
            out int phkResult);

        [DllImport("Advapi32.dll")]
        static extern uint RegCloseKey(int hKey);

        [DllImport("advapi32.dll", EntryPoint = "RegQueryValueEx")]
        public static extern int RegQueryValueEx(
            int hKey, string lpValueName,
            int lpReserved,
            ref uint lpType,
            System.Text.StringBuilder lpData,
            ref uint lpcbData);
        #endregion
        #endregion

        #region Functions
        static public string GetRegKey64(UIntPtr inHive, String inKeyName, String inPropertyName)
        {
            return GetRegKey64(inHive, inKeyName, RegSAM.WOW64_64Key, inPropertyName);
        }

        static public string GetRegKey32(UIntPtr inHive, String inKeyName, String inPropertyName)
        {
            return GetRegKey64(inHive, inKeyName, RegSAM.WOW64_32Key, inPropertyName);
        }

        static public string GetRegKey64(UIntPtr inHive, String inKeyName, RegSAM in32or64key, String inPropertyName)
        {
            //UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002;
            int hkey = 0;

            try
            {
                uint lResult = RegOpenKeyEx(RegHive.HKEY_LOCAL_MACHINE, inKeyName, 0, (int)RegSAM.QueryValue | (int)in32or64key, out hkey);
                if (0 != lResult) return null;
                uint lpType = 0;
                uint lpcbData = 1024;
                StringBuilder AgeBuffer = new StringBuilder(1024);
                RegQueryValueEx(hkey, inPropertyName, 0, ref lpType, AgeBuffer, ref lpcbData);
                string Age = AgeBuffer.ToString();
                return Age;
            }
            finally
            {
                if (0 != hkey) RegCloseKey(hkey);
            }
        }
        #endregion

        #region Enums
        #endregion
    }
}
Here is an example of using this class.
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Read64bitRegistryFrom32bitApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string value64 = RegistryWOW6432.GetRegKey64(RegHive.HKEY_LOCAL_MACHINE, @"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "RegisteredOrganization");
            string value32 = RegistryWOW6432.GetRegKey32(RegHive.HKEY_LOCAL_MACHINE, @"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "RegisteredOrganization");
        }
    }
}

Example 3 – Adding extension methods to the managed RegistryKey object that read the 64 bit registry from a 32 bit application or vice versa

You know what else is a cool idea? Making it an extension class to the normal managed registry C# code. So you can create a regular managed RegistryKey and then just call an extension function off it.
using System;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32;

namespace Read64bitRegistryFrom32bitApp
{
    /// &lt;summary&gt;
    /// An extension class to allow a registry key to allow it to get the
    /// registry in the 32 bit (Wow6432Node) or 64 bit regular registry key
    /// &lt;/summary&gt;
    public static class RegistryWOW6432
    {
        #region Member Variables
        #region Read 64bit Reg from 32bit app
        public static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);
        public static UIntPtr HKEY_CURRENT_USER = new UIntPtr(0x80000001u);

        [DllImport("Advapi32.dll")]
        static extern uint RegOpenKeyEx(
            UIntPtr hKey,
            string lpSubKey,
            uint ulOptions,
            int samDesired,
            out int phkResult);

        [DllImport("Advapi32.dll")]
        static extern uint RegCloseKey(int hKey);

        [DllImport("advapi32.dll", EntryPoint = "RegQueryValueEx")]
        public static extern int RegQueryValueEx(
            int hKey, string lpValueName,
            int lpReserved,
            ref uint lpType,
            System.Text.StringBuilder lpData,
            ref uint lpcbData);
        #endregion
        #endregion

        #region Functions
        public static string GetRegKey64(this RegistryKey inKey, String inPropertyName)
        {
            string strKey = inKey.ToString();
            string regHive = strKey.Split('\\')[0];
            string regPath = strKey.Substring(strKey.IndexOf('\\') +1);
            return GetRegKey64(GetRegHiveFromString(regHive), regPath, RegSAM.WOW64_64Key, inPropertyName);
        }

        public static string GetRegKey32(this RegistryKey inKey, String inPropertyName)
        {
            string strKey = inKey.ToString();
            string regHive = strKey.Split('\\')[0];
            string regPath = strKey.Substring(strKey.IndexOf('\\') + 1);
            return GetRegKey64(GetRegHiveFromString(regHive), regPath, RegSAM.WOW64_32Key, inPropertyName);
        }

        private static UIntPtr GetRegHiveFromString(string inString)
        {
            if (inString == "HKEY_LOCAL_MACHINE")
                return HKEY_LOCAL_MACHINE;
            if (inString == "HKEY_CURRENT_USER")
                return HKEY_CURRENT_USER;
            return UIntPtr.Zero;
        }

        static public string GetRegKey64(UIntPtr inHive, String inKeyName, RegSAM in32or64key, String inPropertyName)
        {
            //UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002;
            int hkey = 0;

            try
            {
                uint lResult = RegOpenKeyEx(inHive, inKeyName, 0, (int)RegSAM.QueryValue | (int)in32or64key, out hkey);
                if (0 != lResult) return null;
                uint lpType = 0;
                uint lpcbData = 1024;
                StringBuilder AgeBuffer = new StringBuilder(1024);
                RegQueryValueEx(hkey, inPropertyName, 0, ref lpType, AgeBuffer, ref lpcbData);
                string Age = AgeBuffer.ToString();
                return Age;
            }
            finally
            {
                if (0 != hkey) RegCloseKey(hkey);
            }
        }
        #endregion

        #region Enums
        public enum RegSAM
        {
            QueryValue = 0x0001,
            SetValue = 0x0002,
            CreateSubKey = 0x0004,
            EnumerateSubKeys = 0x0008,
            Notify = 0x0010,
            CreateLink = 0x0020,
            WOW64_32Key = 0x0200,
            WOW64_64Key = 0x0100,
            WOW64_Res = 0x0300,
            Read = 0x00020019,
            Write = 0x00020006,
            Execute = 0x00020019,
            AllAccess = 0x000f003f
        }
        #endregion
    }
}
Here is an example of using these extension functions.
using System;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32;

namespace Read64bitRegistryFrom32bitApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string value64 = string.Empty;
            string value32 = string.Empty;
            RegistryKey localKey = Registry.LocalMachine;
            localKey = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
            if (localKey != null)
            {
                value32 = localKey.GetRegKey32("RegisteredOrganization");
                value64 = localKey.GetRegKey64("RegisteredOrganization");
            }
        }
    }
}
If anything is confusing please comment.
Resources:
  • RegOpenKeyEx Function – http://msdn.microsoft.com/en-us/library/ms724897%28v=VS.85%29.aspx
  • RegQueryValueEx Function – http://msdn.microsoft.com/en-us/library/ms724911%28VS.85%29.aspx
  • http://www.pinvoke.net/default.aspx/advapi32/RegQueryValueEx.html
  • http://www.pinvoke.net/default.aspx/advapi32/RegOpenKeyEx.html
  • http://www.pinvoke.net/default.aspx/advapi32/RegCreateKeyEx.html
  • http://www.pinvoke.net/default.aspx/advapi32/RegCloseKey.html
  • http://stackoverflow.com/questions/1470770/accessing-registry-using-net
  • http://connect.microsoft.com/VisualStudio/feedback/details/400597/registeredorganization-reg-key-on-x64-vista-7

Copyright ® Rhyous.com – Linking to this post is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.