Using Visual State Manager from a UserControl

To aid in an answer on StackOverflow that I had recently answered, I’m providing part of the response here.

The question was essentially, “what’s a way to use DataTriggers in Silverlight, without DataTriggers?”

I had suggested one idea would just to use VisualStates and a code behind file.

That’s what I’ve done here. I created an enum of type AnimateState, which has three possible values, Top, Left, and Right. By clicking on one of three buttons on the simple UI, it changes the value of the property, which in turn calls one of the VisualStates defined in the XAML.

In the example, it animates the position of the orange ellipse to various positions on the canvas.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace DemoShowVisualStateManager
{    
    public partial class MainPage : UserControl
    {
        private AnimateState _animateState;

        public MainPage()
        {
            InitializeComponent();
        }

        public AnimateState State
        {
            get { return _animateState; }

            set
            {
                if (_animateState != value && Enum.IsDefined(typeof(AnimateState), value))
                {
                    _animateState = value;

                    VisualStateManager.GoToState(this, value.ToString(), true);
                }
            }

        }

        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            AnimateState state;
            if (AnimateState.TryParse((sender as Button).Content.ToString(), out state)) 
            {
                State = state;
            }
            
        }
    }

    public enum AnimateState
    {
        Top,
        Left,
        Right
    }
}

 

<UserControl x:Class="DemoShowVisualStateManager.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Width="500" Height="500">

    <UserControl.Resources>
    </UserControl.Resources>
    <Canvas x:Name="LayoutRoot" Background="White">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="Positions">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:3"/>
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Right">
                    <Storyboard>
                        <DoubleAnimation Duration="0" To="389" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="ball" d:IsOptimized="True"/>
                        <DoubleAnimation Duration="0" To="198" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="ball" d:IsOptimized="True"/>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Left">
                    <Storyboard>
                        <DoubleAnimation Duration="0" To="-199" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="ball" d:IsOptimized="True"/>
                        <DoubleAnimation Duration="0" To="390" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="ball" d:IsOptimized="True"/>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Top"/>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <Ellipse x:Name="ball" Stroke="#FFFFD9B8" RenderTransformOrigin="0.5,0.5" Height="100" VerticalAlignment="Top" Canvas.Top="10" Width="100" Canvas.Left="200">
            <Ellipse.RenderTransform>
                <CompositeTransform/>
            </Ellipse.RenderTransform>
            <Ellipse.Fill>
                <RadialGradientBrush Center="0.388,0.328" GradientOrigin="0.388,0.328" RadiusX="0.63">
                    <GradientStop Color="#FFF97200" Offset="1"/>
                    <GradientStop Color="#FFFFD9B8"/>
                </RadialGradientBrush>
            </Ellipse.Fill>
        </Ellipse>
        <Button Content="Left" Height="33" Canvas.Left="200" Canvas.Top="229" Width="100" Click="Button_Click"/>
        <Button Content="Top" Height="33" Canvas.Left="200" Canvas.Top="266" Width="100" Click="Button_Click"/>
        <Button Content="Right" Height="33" Canvas.Left="200" Canvas.Top="303" Width="100" Click="Button_Click"/>

    </Canvas>
</UserControl>

image

Visual Studio 2010 Add-in Settings Swapper

Challenged by a coworker recently, I created a simple add-in for Visual Studio 2010 to modify the settings for code formatting based on the file extension. The usage scenario is simple: allow for different language formatting rules based on the file file type (or extension). In this case, he wanted to have a different standard for curly brace usage in MVC ASPX pages overriding the default.

The addin, called Settings Swapper may be downloaded from CodePlex and is licensed using the new BSD license.

The documentation is here.

The settings he used for MVC pages are included in the documentation. If you have any questions or issues, either leave a comment here or add something to codeplex.

Enjoy.

Now, a 3rd option, IIS Express

ScottGu announced IIS Express.

IIS Express will become a new way for developers to do local web development in a safe, administrative-account-free way, yet get the full experience of IIS 7. I’d bet the days of the ASP.NET Development server are numbered if IIS Express actually works as well as is suggested (if the same debug/test/run cycle is maintained, and the perf is good, I can’t see any reason why not).

The only bad news is that the announcement precedes the availability of IIS Express and also precedes the availability of patches for VS 2010 to make integration with this new option simple. The latter sounds like it’s farther out than IIS Express itself.

I’d like to see a feature for allowing the web sites hosted within IIS Express to be available from other machines and not just localhost. It would make sharing current development with other team members, QA, managers, etc., much simpler. For developers on older versions of Windows (like XP), they have no option for locally hosting a IIS7 web site and showing it to others. (From the initial blog post, it’s not mentioned if this scenario is supported).

Visual Studio 2010 Crashes Repeatedly

If you have my kind of luck and Visual Studio 2010 crashes every time you open a specific project or solution, try deleting the .suo file associated with the solution (the Visual Studio Solution User Options). It’s located in the same folder as the solution (.sln) file, and often is hidden.

It usually works for me.

The stack dump from the mini-dump taken by Visual Studio isn’t real enlightening. Things went wrong. Smile

     ntdll.dll!@RtlpLowFragHeapFree@8()  + 0x89 bytes   
     ntdll.dll!_RtlFreeHeap@12()  + 0x7e bytes   
     apphelp.dll!_SdbFree@4()  + 0x22 bytes   
     apphelp.dll!_HashFree@4()  + 0x3c bytes   
     apphelp.dll!_SdbpReleaseSearchDBContext@4()  + 0x6d bytes   
     apphelp.dll!_SdbGetMatchingExeEx@32()  + 0x2b9 bytes   
     apphelp.dll!_InternalCheckRunApp@76()  + 0x21c bytes   
     apphelp.dll!_ApphelpCheckRunAppEx@56()  + 0xa7 bytes   
     kernel32.dll!_BaseRestoreImpersonation@4()  – 0x75d55 bytes   
     kernel32.dll!_BaseCheckRunApp@52()  + 0x46 bytes   
     kernel32.dll!_BasepCheckBadapp@60()  + 0x1a1 bytes   
     kernel32.dll!_BasepQueryAppCompat@68()  + 0x63 bytes   
     kernel32.dll!_CreateProcessInternalW@48()  + 0x961 bytes   
>    kernel32.dll!_CreateProcessInternalA@48()  + 0x123 bytes   
     kernel32.dll!_CreateProcessA@40()  + 0x2c bytes   
     devenv.exe!DwCreateProcess()  + 0xc0 bytes   
     devenv.exe!LaunchWatson()  + 0x2b2 bytes   
     devenv.exe!DwExceptionFilterEx()  + 0xed bytes   
     devenv.exe!DwExceptionFilter()  + 0x1f bytes   
     mscoreei.dll!InternalUnhandledExceptionFilter()  + 0x1c bytes   
     kernel32.dll!_UnhandledExceptionFilter@4()  + 0x5e2 bytes   
     ntdll.dll!___RtlUserThreadStart@8()  + 0x369cc bytes   
     ntdll.dll!@_EH4_CallFilterFunc@8()  + 0x12 bytes   
     ntdll.dll!ExecuteHandler2@20()  + 0x26 bytes   
     ntdll.dll!ExecuteHandler@20()  + 0x24 bytes   
     ntdll.dll!_KiUserExceptionDispatcher@8()  + 0xf bytes   
     ntdll.dll!@RtlpLowFragHeapFree@8()  + 0x89 bytes   
     ntdll.dll!_RtlFreeHeap@12()  + 0x7e bytes   
     ole32.dll!CRetailMalloc_Free()  + 0x1c bytes   
     ole32.dll!_CoTaskMemFree@4()  + 0x13 bytes   
     Microsoft.VisualStudio.Editor.Implementation.ni.dll!0daff77b()    
     [Frames below may be incorrect and/or missing, no symbols loaded for Microsoft.VisualStudio.Editor.Implementation.ni.dll]   
     Microsoft.VisualStudio.Editor.Implementation.ni.dll!0daff77b()    
     Microsoft.VisualStudio.Editor.Implementation.ni.dll!0dafdfcd()    
     Microsoft.VisualStudio.Editor.Implementation.ni.dll!0daff642()    
     Microsoft.VisualStudio.Editor.Implementation.ni.dll!0dafdfcd()    
     cslangsvc.dll!CEditFilter::QueryStatus()  + 0x13c bytes   
     cslangsvc.dll!CVsEditFilter::QueryStatus()  + 0x95 bytes   
     mscorlib.ni.dll!5af61753()    
     Microsoft.VisualStudio.Editor.Implementation.ni.dll!0dae99eb()    
     Microsoft.VisualStudio.Editor.Implementation.ni.dll!0dae9a1c()    
     Microsoft.VisualStudio.Platform.WindowManagement.ni.dll!6dce2ae4()    
     Microsoft.VisualStudio.Platform.WindowManagement.ni.dll!6dcdf98c()    
     msenv.dll!CVSCommandTarget::QueryStatusCmd()  + 0x423c bytes   
     msenv.dll!`anonymous namespace’::QueryStatusForController()  + 0x63 bytes   
     msenv.dll!`anonymous namespace’::GetQueryStatusFlags()  + 0x3a bytes   
     msenv.dll!CSurfaceCommandingSupport::IsCommandEnabled()  + 0x1bbb bytes   
     msenv.dll!`anonymous namespace’::DoCommonStateUpdating<CommandUI::Models::IButtonController,`anonymous namespace’::<lambda1> >()  + 0xa2 bytes   
     msenv.dll!CUpdateVisitor::VisitButtonController()  + 0x1b bytes   
     msenv.dll!CControllerVisitorBase::DispatchVisit()  + 0x3bf bytes   
     msenv.dll!CControllerVisitorBase::VisitController()  + 0x22 bytes   
     msenv.dll!CSurfaceCommandingSupport::Update()  + 0x2e bytes   
     msenv.dll!CommandUI::Models::Impl::CControllerBase::Update()  + 0x21 bytes   
     msenv.dll!UpdateChildCollectionWithSeparators()  + 0x17f bytes   
     msenv.dll!CUpdateVisitor::VisitToolBarController()  + 0x2a6 bytes   
     msenv.dll!CControllerVisitorBase::DispatchVisit()  + 0x226 bytes   
     msenv.dll!CControllerVisitorBase::VisitController()  + 0x22 bytes   
     msenv.dll!CSurfaceCommandingSupport::Update()  + 0x2e bytes   
     msenv.dll!UpdateCommandModels()  + 0x147 bytes   
     msenv.dll!CmdUpdateForceInternal()  + 0x28 bytes   
     msenv.dll!CMsoComponent::FDoNonPeriodicIdle()  + 0x991 bytes   
     msenv.dll!CMsoComponent::FDoIdle()  + 0x17 bytes   
     msenv.dll!SCM::FDoIdleLoop()  + 0xf3 bytes   
     msenv.dll!SCM::FDoIdle()  + 0xc7 bytes   
     msenv.dll!SCM_MsoStdCompMgr::FDoIdle()  + 0x13 bytes   
     msenv.dll!CMsoCMHandler::EnvironmentMsgLoop()  + 0x74a bytes   
     msenv.dll!CMsoCMHandler::FPushMessageLoop()  + 0x79 bytes   
     msenv.dll!SCM::FPushMessageLoop()  + 0x8c bytes   
     msenv.dll!SCM_MsoCompMgr::FPushMessageLoop()  + 0x2a bytes   
     msenv.dll!CMsoComponent::PushMsgLoop()  + 0x28 bytes   
     msenv.dll!VStudioMainLogged()  + 0x22a bytes   
     msenv.dll!_VStudioMain()  + 0x78 bytes   
     devenv.exe!util_CallVsMain()  + 0xdb bytes   
     devenv.exe!CDevEnvAppId::Run()  + 0x693 bytes   
     devenv.exe!_WinMain@16()  + 0x88 bytes   
     devenv.exe!operator new[]()  + 0xa59d bytes   
     kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes   
     ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
     ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes