Using VisualStateManager in WPF

Topics: Prism v2 - WPF 3.5
Jul 26, 2009 at 5:37 PM

I have begun to learn about WPF and using Prism to create Composite WPF apps.  I am using the StockTraderRI and trying to implement parts of it in my app.  I am trying to use the checkmark radio buttons and having a problem because the control uses the VisualStateManager.  MSDN indicates that the VSM is in System.Windows.  First, I don't see that assembly referenced by the StockTraderRI desktop app.  Second,  when I do reference it from C:\Program Files\Microsoft Silverlight\3.0.40624.0 I get other errors relating to the XAML syntax in the control template (Error 1 The object 'VisualStateGroup' already has a child and cannot add 'VisualState'. 'VisualStateGroup' can accept only one child.)  What am I missing?  Thanks for all the work that the team has put into Prism!  I know it will be very useful once I have struggled up the learing curve a bit.

Jul 27, 2009 at 6:10 PM

Hi

The VisualStateManager class does not exist in WPF 3.5, but does in WPF 4.0 (also in the WPF 3.5 SP1 toolkit). You are probably checking out the Silverlight reference implementation (which does have a reference to System.Windows.dll in the Shell project) and not the WPF solution. As you are using WPF and not Silverlight, you won’t be able to use the VisualStateManager from the Silverlight assemblies.

You can check the StockTraderRI_Desktop.sln which only targets WPF. In this solution, the same control is implemented for WPF, so you can take the implementation from there.

Please let me know if this helps.

Damian Schenkelman
http://blogs.southworks.net/dschenkelman

Jul 27, 2009 at 11:35 PM
Damian,
Would you please clarify your answer to my question about the VisualStateManager. I am looking at the app.xaml file for the Desktop version of the StockTraderRI. Several of the control templates use the VisualStateManager via the following namespace declaration -- xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows". However, I do not see the System.Windows assembly in the list of references displayed in Solution Manager for the app. The app builds and appears to run. I have Microsoft .NET Framework 3.5 SP1 because it was listed in the download details for Prism as a prerequisite. I don't believe that I have the WPF Toolkit.
How is this working? How can I use these control templates in my own WPF app?
Thanks in advance,
Rick Burke
-----Original Message-----
From: dschenkelman [mailto:notifications@codeplex.com]
Sent: Monday, July 27, 2009 1:10 PM
To: rickburke133@windstream.net
Subject: Re: Using VisualStateManager in WPF [CompositeWPF:63573]

From: dschenkelman

Hi

The VisualStateManager class does not exist in WPF 3.5, but does in WPF 4.0 (also in the WPF 3.5 SP1 toolkit). You are probably checking out the Silverlight reference implementation (which does have a reference to System.Windows.dll in the Shell project) and not the WPF solution. As you are using WPF and not Silverlight, you won’t be able to use the VisualStateManager from the Silverlight assemblies.

You can check the StockTraderRI_Desktop.sln which only targets WPF. In this solution, the same control is implemented for WPF, so you can take the implementation from there.

Please let me know if this helps.

Damian Schenkelman
http://blogs.southworks.net/dschenkelman

Jul 30, 2009 at 5:31 PM

Hi Rick

I apologize for not being clear in my previous answer. I will try to summarize my thoughts. The VisualStateManager control is not used in the WPF Reference Implementation. The VisualStateManager control is used by the Silverlight Reference Implementation. If you are using the StockTraderRI.sln file, you have both WPF & Silverlight RI.

 

To get the checkable radio button for WPF implementation you must:

  1. Open the StockTraderRI_Desktop.sln (~DecompressionFolder\RI\StockTraderRI_Desktop.sln).
  2. Find the Styles.xaml file in that solution. It is in the Resources folder of the Shell project.
  3. Look for the style with the following signature: <Style x:Key="{x:Type RadioButton}" TargetType="{x:Type RadioButton}">

The following is the entire style. This style uses brushes that are also in the Styles.xaml file, so you must first copy them to be able to use them:

<Style x:Key="{x:Type RadioButton}" TargetType="{x:Type RadioButton}">
        <Setter Property="SnapsToDevicePixels" Value="true"/>
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="FocusVisualStyle"    Value="{StaticResource RadioButtonFocusVisual}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RadioButton}">
                    <BulletDecorator Background="Transparent">
                        <BulletDecorator.Bullet>
                            <Grid Width="13" 
                Height="13" >
                                <Ellipse x:Name="Border"  
                  Fill="{StaticResource NormalBrush}"
                  StrokeThickness="1"
                  Stroke="{StaticResource NormalBorderBrush}" />
                                <Path Height="8" x:Name="CheckMark" Width="8" Opacity="1" Fill="{StaticResource GlyphBrush}"
                          Stretch="Fill" 
                          Data="M102.03442,598.79645 L105.22962,597.78918 L106.78825,600.42358 C106.78825,600.42358 108.51028,595.74304 110.21724,593.60419 C112.00967,591.35822 114.89314,591.42316 114.89314,591.42316 C114.89314,591.42316 112.67844,593.42645 111.93174,594.44464 C110.7449,596.06293 107.15683,604.13837 107.15683,604.13837 z" 
                          Canvas.ZIndex="1"/>
                            </Grid>
                        </BulletDecorator.Bullet>
                        <ContentPresenter 
              Margin="4,0,0,0"
              VerticalAlignment="Center"
              HorizontalAlignment="Left"
              RecognizesAccessKey="True"/>
                    </BulletDecorator>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="false">
                            <Setter TargetName="CheckMark" Property="Visibility" Value="Collapsed"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="Border" Property="Fill" Value="{StaticResource DarkBrush}" />
                        </Trigger>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter TargetName="Border" Property="Fill" Value="{StaticResource PressedBrush}" />
                            <Setter TargetName="Border" Property="Stroke" Value="{StaticResource GlyphBrush}" />
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter TargetName="Border" Property="Fill" Value="{StaticResource DisabledBackgroundBrush}" />
                            <Setter TargetName="Border" Property="Stroke" Value="#40000000" />
                            <Setter Property="Foreground" Value="#80000000"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

 

 

Please let me know if this helps.

 

Damian Schenkelman
http://blogs.southworks.net/dschenkelman

Jul 30, 2009 at 9:52 PM
Damian,
Yes, thanks!
I did have the WPF&Silverlight RI solution open, but was looking at the code in the Desktop folder which I thought was code for the WPF app. My bad!!!
Thanks,
Rick Burke
-----Original Message-----
From: dschenkelman [mailto:notifications@codeplex.com]
Sent: Thursday, July 30, 2009 12:31 PM
To: rickburke133@windstream.net
Subject: Re: Using VisualStateManager in WPF [CompositeWPF:63573]

From: dschenkelman

Hi Rick

I apologize for not being clear in my previous answer. I will try to summarize my thoughts. The VisualStateManager control is not used in the WPF Reference Implementation. The VisualStateManager control is used by the Silverlight Reference Implementation. If you are using the StockTraderRI.sln file, you have both WPF & Silverlight RI.

To get the checkable radio button for WPF implementation you must:

  1. Open the StockTraderRI_Desktop.sln (~DecompressionFolder\RI\StockTraderRI_Desktop.sln).
  2. Find the Styles.xaml file in that solution. It is in the Resources folder of the Shell project.
  3. Look for the style with the following signature: <Style x:Key="{x:Type RadioButton}" TargetType="{x:Type RadioButton}">

The following is the entire style. This style uses brushes that are also in the Styles.xaml file, so you must first copy them to be able to use them:

<Style x:Key="{x:Type RadioButton}" TargetType="{x:Type RadioButton}">
        <Setter Property="SnapsToDevicePixels" Value="true"/>
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="FocusVisualStyle"    Value="{StaticResource RadioButtonFocusVisual}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RadioButton}">
                    <BulletDecorator Background="Transparent">
                        <BulletDecorator.Bullet>
                            <Grid Width="13" 
                Height="13" >
                                <Ellipse x:Name="Border"  
                  Fill="{StaticResource NormalBrush}"
                  StrokeThickness="1"
                  Stroke="{StaticResource NormalBorderBrush}" />
                                <Path Height="8" x:Name="CheckMark" Width="8" Opacity="1" Fill="{StaticResource GlyphBrush}"
                          Stretch="Fill" 
                          Data="M102.03442,598.79645 L105.22962,597.78918 L106.78825,600.42358 C106.78825,600.42358 108.51028,595.74304 110.21724,593.60419 C112.00967,591.35822 114.89314,591.42316 114.89314,591.42316 C114.89314,591.42316 112.67844,593.42645 111.93174,594.44464 C110.7449,596.06293 107.15683,604.13837 107.15683,604.13837 z" 
                          Canvas.ZIndex="1"/>
                            </Grid>
                        </BulletDecorator.Bullet>
                        <ContentPresenter 
              Margin="4,0,0,0"
              VerticalAlignment="Center"
              HorizontalAlignment="Left"
              RecognizesAccessKey="True"/>
                    </BulletDecorator>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="false">
                            <Setter TargetName="CheckMark" Property="Visibility" Value="Collapsed"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="Border" Property="Fill" Value="{StaticResource DarkBrush}" />
                        </Trigger>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter TargetName="Border" Property="Fill" Value="{StaticResource PressedBrush}" />
                            <Setter TargetName="Border" Property="Stroke" Value="{StaticResource GlyphBrush}" />
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter TargetName="Border" Property="Fill" Value="{StaticResource DisabledBackgroundBrush}" />
                            <Setter TargetName="Border" Property="Stroke" Value="#40000000" />
                            <Setter Property="Foreground" Value="#80000000"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Please let me know if this helps.

Damian Schenkelman
http://blogs.southworks.net/dschenkelman