Archive for the ‘IDEs’ Category.

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 allows for rapid development that is much faster 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 and portshaker-config

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

Note: Notice I didn’t just install portshaker, I installed portshaker-config which has portshaker as a dependency, so you get both installed with one command.

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 diffed and chose either install or continue each time.

Note: Running portshaker uses subversion to download so if you need to use an HTTP proxy, you have to configure subversion to use an HTTP proxy as it doesn’t use the FreeBSD HTTP_PROXY environment variable.

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

Visual Studo Power Tools

I just installed Visual Studio Power Tools.

Visual Studio Power Tools | MSDN

I will see if there are features that I actually use.

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 to 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
{
    /// <summary>
    /// 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
    /// </summary>
    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 RegistryValueKind lpType,
            StringBuilder lpData,
            ref uint lpcbData);

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegQueryValueEx")]
        private static extern int RegQueryValueEx(
            int hKey,
            string lpValueName,
            int lpReserved,
            ref RegistryValueKind lpType,
            [Out] byte[] 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);
        }

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

        public static byte[] GetRegKey32AsByteArray(this RegistryKey inKey, String inPropertyName)
        {
            string strKey = inKey.ToString();
            string regHive = strKey.Split('\\')[0];
            string regPath = strKey.Substring(strKey.IndexOf('\\') + 1);
            return GetRegKey64AsByteArray(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;
                RegistryValueKind lpType = 0;
                uint lpcbData = 1024;
                StringBuilder strBuffer = new StringBuilder(1024);
                RegQueryValueEx(hkey, inPropertyName, 0, ref lpType, strBuffer, ref lpcbData);
                string value = strBuffer.ToString();
                return value;
            }
            finally
            {
                if (0 != hkey) RegCloseKey(hkey);
            }
        }

        static public byte[] GetRegKey64AsByteArray(UIntPtr inHive, String inKeyName, RegSAM in32or64key, String inPropertyName)
        {
            int hkey = 0;

            try
            {
                uint lResult = RegOpenKeyEx(inHive, inKeyName, 0, (int)RegSAM.QueryValue | (int)in32or64key, out hkey);
                if (0 != lResult) return null;
                RegistryValueKind lpType = 0;
                uint lpcbData = 2048;

                // Just make a big buffer the first time
                byte[] byteBuffer = new byte[1000];
                // The first time, get the real size
                RegQueryValueEx(hkey, inPropertyName, 0, ref lpType, byteBuffer, ref lpcbData);
                // Now create a correctly sized buffer
                byteBuffer = new byte[lpcbData];
                // now get the real value
                RegQueryValueEx(hkey, inPropertyName, 0, ref lpType, byteBuffer, ref lpcbData);

                return byteBuffer;
            }
            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 Microsoft.Win32;

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

            byte[] byteValue64 = new byte[1024];
            byte[] byteValue32 = new byte[1024];
            RegistryKey localKey = Registry.LocalMachine;

            localKey = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
            if (localKey != null)
            {
                value32 = localKey.GetRegKey32("RegisteredOrganization");
                value64 = localKey.GetRegKey64("RegisteredOrganization");

                // byteValue32 = localKey.GetRegKey32AsByteArray("DigitalProductId"); // Key doesn't exist by default in 32 bit
                byteValue64 = localKey.GetRegKey64AsByteArray("DigitalProductId");
            }
        }
    }
}
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.

C# (Mono) – Reading and writing to a text file

C# (Mono) on FreeBSD
File access is made simple with C# (Mono) on FreeBSD.

Reading a text file with C# (Mono)

To read a file, use a StreamReader object. However, it is easy if you don’t do a new StreamWriter("File.txt") but instead use File.OpenText("File.txt") to create the StreamReader. Once you have the stream, you just need to run the stream’s ReadToEnd() function.

Here is a snippet to read a text file as a string.

// Open the file into a StreamReader
StreamReader file = File.OpenText("SomeFile.txt");
// Read the file into a string
string s = file.ReadToEnd();

Now that you have the text file as a string, you can manipulate the string as you desire.

Writing to a text file with C# (Mono)

To write a text file, use StreamWriter.

string str = "Some text";
// Hook a write to the text file.
StreamWriter writer = new StreamWriter("SomeFile.txt");
// Rewrite the entire value of s to the file
writer.Write(str);

You can also just add a line to the end of the file as follows:

string str = "Some text";
// Hook a write to the text file.
StreamWriter writer = new StreamWriter("SomeFile.txt");
// Rewrite the entire value of s to the file
writer.WriteLine(str);

Example for learning

An example of these in a little project file made with MonoDevelop.

using System;
using System.IO;

namespace FileAccess
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			string FileName="TestFile.txt";

			// Open the file into a StreamReader
			StreamReader file = File.OpenText(FileName);
			// Read the file into a string
			string s = file.ReadToEnd();
			// Close the file so it can be accessed again.
			file.Close();

			// Add a line to the text
			s  += "A new line.\n";

			// Hook a write to the text file.
			StreamWriter writer = new StreamWriter(FileName);
			// Rewrite the entire value of s to the file
			writer.Write(s);

			// Add a single line
			writer.WriteLine("Add a single line.");

			// Close the writer
			writer.Close();
		}
	}
}

Well, this should get you started.

A Visual Studio snippet for a class with #region sections

Here is a simple snippet to add to Visual Studio if you want:

Place it here for Visual Studio 2010: C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC#\Snippets\1033\Visual C#

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>classr</Title>
			<Shortcut>classr</Shortcut>
			<Description>Code snippet for class with prepopulated regions.</Description>
			<Author>Microsoft Corporation</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
				<SnippetType>SurroundsWith</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal>
					<ID>name</ID>
					<ToolTip>Class name</ToolTip>
					<Default>MyClass</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp"><![CDATA[class $name$
	{
	#region Member Fields
	#endregion

	#region Constructor
	/// <summary>
	/// The default constructor
	/// </summary>
	public $name$()
	{
	}
	#endregion

	#region Properties
	#endregion

	#region Functions
	#endregion

	#region enums
	#endregion
		$selected$$end$
	}]]>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

A Progress Bar using WPF’s ProgressBar Control, BackgroundWorker, and MVVM

WPF provides a ProgressBar control.  But there isn’t really a manual for it, especially if you want to follow MVVM.

So I am going to make a little application that counts from zero to ten and tracks the progress.  You are going to see when it is OK to use the foreground and when it is not OK but better to use BackgroundWorker.

While much of this code may be production ready, you should be aware that this code intentionally implements a foreground process that is an example of what not to do.

Prerequisites

  • Visual Studio

Step 1 – Create a new WPF Application Project

  1. In Visual Studio, create a new Solution and choose WPF Application
  2. Give it a name.
  3. Hit OK.

Step 2 – Add two base MVVM files

There are two basic classes used for MVVM.

  • RelayCommand
  • ViewModelBase

These are found on different blogs and different posts all over the internet, so I would say they are public domain, or free and unlicensed.

  1. Download them zipped here. MVVM
  2. Extract the zip file.
  3. Add the MVVM folder and the two class under it to your project.

Step 3 – Create a ProgressBarViewModel class

  1. Create a new Class called ProgressBarViewModel.
  2. Adding a using MVVM statement at the top.
  3. Make the class inherit ViewModelBase.
    class ProgressBarViewModel : ViewModelBase
    {
    }
    

This will be populated as we create our View.

Step 4 – Design the GUI in MainWindow.xaml

Ok, so lets create the GUI.

  1. Add a local reference. (Line 4)
  2. Add a ProgressBarViewModel object as a resource. (Lines 6-8)
  3. Create a StackPanel in the default Grid to put everything in. (Line 10)
  4. Add a one character label in great big text to display our number. (Line 11)
  5. Add a ProgressBar element. (Line 12)
  6. Create buttons to manipulate the label. (Lines 13-16)
  7. Configure the DataContext of each element to be the the ProgressBarViewModel using the Key PBVM we gave it when we added it as a resource. (Lines 11-16)
  8. Think of and create Binding Paths for each element. Yes, we can basically just make these Path names up and add them to the ProgressBarViewModel later. (Lines 11-16)

Here is the XAML.

<Window x:Class=&quot;WPFProgressBarUsingBackgroundWorker.MainWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:local=&quot;clr-namespace:WPFProgressBarUsingBackgroundWorker&quot;
        Title=&quot;MainWindow&quot; >
    <Window.Resources>
        <local:ProgressBarViewModel x:Key=&quot;PBVM&quot; />
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Label Content=&quot;{Binding Path=Value}&quot; DataContext=&quot;{StaticResource ResourceKey=PBVM}&quot; HorizontalAlignment=&quot;Stretch&quot; HorizontalContentAlignment=&quot;Center&quot; Name=&quot;labelNumberCounter&quot; VerticalAlignment=&quot;Center&quot; FontSize=&quot;175&quot; />
            <ProgressBar Margin=&quot;0,3,0,3&quot; Height=&quot;20&quot; Name=&quot;progressBar&quot; Value=&quot;{Binding Path=Value}&quot; DataContext=&quot;{StaticResource ResourceKey=PBVM}&quot; Minimum=&quot;{Binding Min}&quot; Maximum=&quot;{Binding Max}&quot;/>
            <Button Command=&quot;{Binding Path=IncrementBy1}&quot; Content=&quot;Manual Count&quot; DataContext=&quot;{StaticResource PBVM}&quot; Height=&quot;23&quot; IsEnabled=&quot;{Binding Path=IsNotInProgress}&quot; Name=&quot;button1&quot; Width=&quot;Auto&quot; />
            <Button Margin=&quot;0,3,0,3&quot; IsEnabled=&quot;{Binding Path=IsNotInProgress}&quot; Command=&quot;{Binding Path=IncrementAsForegroundProcess}&quot; DataContext=&quot;{StaticResource ResourceKey=PBVM}&quot; Content=&quot;Count to 10 as a foreground process&quot; HorizontalAlignment=&quot;Stretch&quot; Height=&quot;23&quot; Name=&quot;buttonForeground&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;Auto&quot; />
            <Button Margin=&quot;0,3,0,3&quot; IsEnabled=&quot;{Binding Path=IsNotInProgress}&quot; Command=&quot;{Binding Path=IncrementAsBackgroundProcess}&quot; DataContext=&quot;{StaticResource ResourceKey=PBVM}&quot; Content=&quot;Count to 10 as a background process&quot; HorizontalAlignment=&quot;Stretch&quot; Height=&quot;23&quot; Name=&quot;buttonBackground&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;Auto&quot; />
            <Button Command=&quot;{Binding Path=ResetCounter}&quot; Content=&quot;Reset&quot; DataContext=&quot;{StaticResource PBVM}&quot; Height=&quot;23&quot; IsEnabled=&quot;{Binding Path=IsNotInProgress}&quot; Name=&quot;buttonReset&quot; Width=&quot;Auto&quot; />
        </StackPanel>
    </Grid>
</Window>

Step 5 – Populate the ProgressBarViewModel

  1. Create the following member fields.
    • Double _Value;
    • bool _IsInProgress;
    • int _Min = 0;
    • int _Max = 10;
  2. Create a matching property for each member field. Make sure that in the set function of the property you call NotifyPropertyChanged(“PropertyName”).
  3. Create a function for each of the four buttons and populate these functions with the code. See the functions in the code below:
    • Increment()
    • IncrementProgressForeground()
    • IncrementProgressBackgroundWorker()
    • Reset()
  4. Create and populate the functions for the BackgroundWorker.
    • worker_DoWork
    • worker_RunWorkerCompleted()
  5. Create the following RelayCommand instances as member Fields.
    • RelayCommand _Increment;
    • RelayCommand _IncrementBy1;
    • RelayCommand _IncrementAsBackgroundProcess;
    • RelayCommand _ResetCounter;
  6. Create matching ICommand properties for each RelayCommand, instantiating the RelayCommand with the correct function.

Here is the code for the ProgressBarViewModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Text;
using System.Windows.Input;
using MVVM;

namespace WPFProgressBarUsingBackgroundWorker
{
    class ProgressBarViewModel : ViewModelBase
    {
        #region Member Fields
        Double _Value;
        bool _IsInProgress;
        int _Min = 0, _Max = 10;
        #endregion

        #region Member RelayCommands that implement ICommand
        RelayCommand _Increment;
        RelayCommand _IncrementBy1;
        RelayCommand _IncrementAsBackgroundProcess;
        RelayCommand _ResetCounter;
        #endregion

        #region Constructors
        /// <summary>
        /// The default constructor
        /// </summary>
        public ProgressBarViewModel()
        {
        }
        #endregion

        #region Properties
        /// <summary>
        /// Used to mark if the counter is in progress so the counter can't be started
        /// while it is already running.
        /// </summary>
        public bool IsInProgress
        {
            get { return _IsInProgress; }
            set
            {
                _IsInProgress = value;
                NotifyPropertyChanged(&quot;IsInProgress&quot;);
                NotifyPropertyChanged(&quot;IsNotInProgress&quot;);
            }
        }

        public bool IsNotInProgress
        {
            get { return !IsInProgress; }
        }

        public int Max
        {
            get { return _Max; }
            set { _Max = value; NotifyPropertyChanged(&quot;Max&quot;); }
        }

        public int Min
        {
            get { return _Min; }
            set { _Min = value; NotifyPropertyChanged(&quot;Min&quot;); }
        }

        /// <summary>
        /// This is the Value.  The Counter should display this.
        /// </summary>
        public Double Value
        {
            get { return _Value; }
            set
            {
                if (value <= _Max)
                {
                    if (value >= _Min) { _Value = value; }
                    else { _Value = _Min; }
                }
                else { _Value = _Max; }
                NotifyPropertyChanged(&quot;Value&quot;);
            }
        }

        #region ICommand Properties
        /// <summary>
        /// An ICommand representation of the Increment() function.
        /// </summary>
        public ICommand IncrementBy1
        {
            get
            {
                if (_IncrementBy1 == null)
                {
                    _IncrementBy1 = new RelayCommand(param => this.Increment());
                }
                return _IncrementBy1;
            }
        }

        /// <summary>
        /// An ICommand representation of the IncrementProgressForegroundWorker() function.
        /// </summary>
        public ICommand IncrementAsForegroundProcess
        {
            get
            {
                if (_Increment == null)
                {
                    _Increment = new RelayCommand(param => this.IncrementProgressForeground());
                }
                return _Increment;
            }
        }

        /// <summary>
        /// An ICommand representation of the IncrementProgressForeground() function.
        /// </summary>
        public ICommand IncrementAsBackgroundProcess
        {
            get
            {
                if (_IncrementAsBackgroundProcess == null)
                {
                    _IncrementAsBackgroundProcess = new RelayCommand(param => this.IncrementProgressBackgroundWorker());
                }
                return _IncrementAsBackgroundProcess;
            }
        }

        /// <summary>
        /// An ICommand representation of the Reset() function.
        /// </summary>
        public ICommand ResetCounter
        {
            get
            {
                if (_ResetCounter == null)
                {
                    _ResetCounter = new RelayCommand(param => this.Reset());
                }
                return _ResetCounter;
            }
        }
        #endregion ICommand Properties
        #endregion

        #region Functions
        /// <summary>
        /// This function manually increments the counter by 1 in the foreground.
        /// Because it only increments by one, the WPF control bound to Value will
        /// display the new value when this function completes.
        /// </summary>
        public void Increment()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;

            // If the value is already at 10, start the counting over.
            if (Value == 10)
                Reset();
            Value++;
        }

        /// <summary>
        /// This function starts the counter as a foreground process.
        /// This doesn't work.  It counts to 10 but the UI is not updated
        /// until the function completes.  This is especially problematic
        /// since the buttons are left enabled.
        /// </summary>
        public void IncrementProgressForeground()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;
            Reset();
            IsInProgress = true;
            Value = 0;
            for (int i = _Min; i < _Max; i++)
            {
                Value++;
                Thread.Sleep(1000);
            }
            IsInProgress = false;
        }

        /// <summary>
        /// This starts the counter as a background process.
        /// </summary>
        public void IncrementProgressBackgroundWorker()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;

            Reset();
            IsInProgress = true;
            BackgroundWorker worker = new BackgroundWorker();
            // Configure the function that will run when started
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);

            /*The progress reporting is not needed with this implementation and is therefore
            commented out.  However, in your more complex application, you may have a use for
            for this.

            //Enable progress and configure the progress function
            worker.WorkerReportsProgress = true;
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);

            */

            // Configure the function to run when completed
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

            // Launch the worker
            worker.RunWorkerAsync();
        }

        /// <summary>
        /// This is the function that is called when the worker is launched with the RunWorkerAsync() call.
        /// </summary>
        /// <param name=&quot;sender&quot;>The worker as Object, but it can be cast to a worker.</param>
        /// <param name=&quot;e&quot;>The DoWorkEventArgs object.</param>
        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = _Min; i < _Max; i++)
            {
                Value++;
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// This worker_ProgressChanged function is not in use for this project. Thanks to INotifyPropertyChanged, this is
        /// completely unnecessary.
        /// </summary>
        /// <param name=&quot;sender&quot;>The worker as Object, but it can be cast to a worker.</param>
        /// <param name=&quot;e&quot;>The ProgressChangedEventArgs object.</param>
        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Does nothing yet
            throw new NotImplementedException();
        }

        /// <summary>
        /// This worker_RunWorkerCompleted is called when the worker is finished.
        /// </summary>
        /// <param name=&quot;sender&quot;>The worker as Object, but it can be cast to a worker.</param>
        /// <param name=&quot;e&quot;>The RunWorkerCompletedEventArgs object.</param>
        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            IsInProgress = false;
        }

        /// <summary>
        /// This function resets the Value of the counter to 0.
        /// </summary>
        private void Reset()
        {
            Value = Min;
        }
        #endregion
    }
}

I’m sorry that this is not the most Newbie proof post. But I tried to comment like crazy the code so you can get through it.

Now if you find a discrepancy in my walk-through, please comment. Also, if it is easier for you to just download the project, here it is:
WPFProgressBarUsingBackgroundWorker.zip

Russian Government going Open Source…and the future

Well, I have seen governments claim they are going to open source before, but not from Russia, and not with such a realistic plan to migrate over a few years.

Here is a link to the article via Google translate:

Putin ordered the transfer of power on Linux

The now

Business drives software development.  Open Source communities help, but even today much of the ongoing development for Linux is driven by businesses such as Red Hat and Novell and others.  If you think your Linux code is being written by unpaid developers in their spare time, you are somewhat correct but only partially.  Most changes are made by developers who are paid.

While communities are nice, they can’t match the hours or output of experienced developers working forty to sixty hours a week.

Looking Ahead…the Apps…and C# (Mono)

The more open source is used in business, the more development power it will have.  But it is not the open source Operatings Systems that prevent people from moving to Linux or BSD.  Ubuntu, SUSE, Fedora, CentOS, PC-BSD, and numerous others are all very usable desktops that are user friendly.  It is the software that runs on them that everyone is waiting for.

The market is already there to make millions extra if you application runs cross platform, one Windows, MAC, Linux, and BSD.

But most the applications written for Windows, the business desktop of today, are using .NET Framework. So naturally those companies are going to want to make their code cross platform.  And they are going to find it is easier than they thought to move their applications between platforms using C#.  I have recently decided that C# is the future of applications on all platforms.

Some MAC and Linux users don’t like Microsoft and will fight off the idea of a Microsoft provided development platform such as C# (Mono) on their systems.  But when a corporation decides that you must run software X, and software X requires .NET, and you have to either give up your MAC or Linux box for a Windows box, or use C# (Mono), then users will come around.

If you are a company writing software for Windows only today and using C#, you need to take a look at Mono. Even if the return on investment of developing a C# (Mono) based version of your product is a slight loss to break even, it is an investment in the future.  Once written, maintenance costs will be less than the original development costs and that slight loss to break even margin will turn to a small profit.  And with the experience, you next app will migrate to C# (Mono) that much easier and soon, all you apps will run anywhere that C# (Mono) can run.

This is going to take off in a way Java hasn’t because developers for windows prefer and will continue to prefer .NET over Java.  And when it comes to business apps, Java just isn’t the language of choice.  Business applications are written in C#.

VMWare, RDP (MSTSC), WPF, and DisableHWAcceleration

I don’t know if you, like me, have a development box running Visual Studio 2010 and VMWare workstation. I develop in C# and WPF, and test the product in a VM. Then sometimes, when I work from home, I remote desktop into my development box.

When I am using RDP to remote control a VMWare Workstation host, and I run a WPF Application inside a VM, the WPF application doesn’t display. The window opens, and you see the frame of your windows, but the inside is just blank or a white/gray box. None of the WPF Controls are visible.

I have found two ways to fix this. One is permanent and one is temporary.

Option 1 – (Permanent) Set this registry key. Read more about this here on MSDN: Graphics Rendering Registry Settings

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Avalon.Graphics]
"DisableHWAcceleration"=dword:00000001

Option 2 – (Temporary) Or just reboot the VM while connected to the VMWare Workstation host via RDP. It seems that the VM boots and the OS detects the lack of support and disabled hardware acceleration. However, once you reboot when you are not RDP’ed into the VMWare Workstation host, you have hardware acceleration back.

I took me a long time to figure this out, because there was little to nothing in a Google search. I came across this solution while looking for something else a month or so ago, and needed to use it again when working from home last night. I thought I would post it so I never have to look for it again.