IVisualStateManager + Window

Jun 22, 2010 at 12:19 PM
Edited Jun 22, 2010 at 12:24 PM

hi marlon, in my project i have a loginscreen. i show this OnStartup() in app.xaml.cs. all works fine but not switching visualstates from vm :)

<Window x:Class="Kabu.Login"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:mefed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF" 
        Title="Bitte Melden Sie sich an:"
        SizeToContent="WidthAndHeight" 
        MinWidth="400" MinHeight="200" 
	    ResizeMode="NoResize" 
	    FontSize="12"
        mefed:ViewModelLocator.ViewModel="Kabu.ViewModel.LoginVM">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="LoginStates">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:2">
                        <VisualTransition.GeneratedEasingFunction>
                            <BounceEase EasingMode="EaseOut"/>
                        </VisualTransition.GeneratedEasingFunction>
                    </VisualTransition>
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Loading">
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" 
                                                       Storyboard.TargetName="border">
                            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                        </DoubleAnimationUsingKeyFrames>
                        <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsHitTestVisible)" 
                                                        Storyboard.TargetName="border">
                            <DiscreteBooleanKeyFrame KeyTime="0" Value="True"/>
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Normal"/>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        
            <Border x:Name="border" Grid.RowSpan="2" IsHitTestVisible="False" Background="Gray" Opacity="0" />
        </Grid>
</Window>

in my viewmodel i do the following:

[PartCreationPolicy(CreationPolicy.Shared)]
    [ExportViewModel("Kabu.ViewModel.LoginVM")]
    public class LoginVM : ViewModelBase
    {
        //services
        private IVisualStateManager stateManager;

        [ImportingConstructor]
        public LoginVM(IVisualStateManager stateManager)
        {
            this.stateManager = stateManager;

...
...
...


this.stateManager.GoToState("Loading");

Your samples works well, maybe its because i try this on a window?
i hope you can give me a hint :)

thx frank

Coordinator
Jun 22, 2010 at 12:36 PM
looks good can you send me a sample?

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



On Tue, Jun 22, 2010 at 1:19 PM, blindmeis <notifications@codeplex.com> wrote:

From: blindmeis

hi marlon, in my project i have a loginscreen, which is called  OnStartup() in app.xaml.cs. all works fine but not switching visualstates from vm :)

<Window x:Class="Kabu.Login"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:mefed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF" 
        Title="Bitte Melden Sie sich an:"
        SizeToContent="WidthAndHeight" 
        MinWidth="400" MinHeight="200" 
	    ResizeMode="NoResize" 
	    FontSize="12"
        mefed:ViewModelLocator.ViewModel="Kabu.ViewModel.LoginVM">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="LoginStates">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:2">
                        <VisualTransition.GeneratedEasingFunction>
                            <BounceEase EasingMode="EaseOut"/>
                        </VisualTransition.GeneratedEasingFunction>
                    </VisualTransition>
                </VisualStateGroup.Transitions>
                <VisualState x:Name="Loading">
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" 
                                                       Storyboard.TargetName="border">
                            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                        </DoubleAnimationUsingKeyFrames>
                        <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.IsHitTestVisible)" 
                                                        Storyboard.TargetName="border">
                            <DiscreteBooleanKeyFrame KeyTime="0" Value="True"/>
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Normal"/>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        
            <Border x:Name="border" Grid.RowSpan="2" IsHitTestVisible="False" Background="Gray" Opacity="0" />
        </Grid>
</Window>

in my viewmodel i do the following:

[PartCreationPolicy(CreationPolicy.Shared)]
    [ExportViewModel("Kabu.ViewModel.LoginVM")]
    public class LoginVM : ViewModelBase
    {
        //services
        private IVisualStateManager stateManager;

        [ImportingConstructor]
        public LoginVM(IVisualStateManager stateManager)
        {
            this.stateManager = stateManager;

...
...
...


this.stateManager.GoToState("Loading");

Your samples works well, maybe its because i try this on a window?
i hope you can give me a hint :)

thx frank

Read the full discussion online.

To add a post to this discussion, reply to this email (MEFedMVVM@discussions.codeplex.com)

To start a new discussion for this project, email MEFedMVVM@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Jun 22, 2010 at 1:08 PM
Edited Jun 22, 2010 at 1:36 PM

sample project is on the way. i sent it to your email from your blog.
is the any way to sent an email with attachment from codeplex to you?

edit: Delivery to the following recipients failed. ....

How should i sent you the sample project? :)

 

Coordinator
Jun 22, 2010 at 1:58 PM
no just use my personal email.... its marlongrech AT gmail DOT com... remove the AT and DOT I use those because of web crawlers spammers...
Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



On Tue, Jun 22, 2010 at 2:09 PM, blindmeis <notifications@codeplex.com> wrote:

From: blindmeis

sample project is on the way. i sent it to your email from your blog.
is the any way to sent an email with attachment from codeplex to you?

Read the full discussion online.

To add a post to this discussion, reply to this email (MEFedMVVM@discussions.codeplex.com)

To start a new discussion for this project, email MEFedMVVM@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Jun 23, 2010 at 8:14 AM

finally! the sample project is on the way ;)

Jul 1, 2010 at 9:36 AM

hi, it seems the problem is the Window object, vsm did not invoke actions then.  btw i now use the trigger+action from cinch2 for changing visualstates. works like a charm :)

Jul 2, 2010 at 8:11 AM

damn :) with one solution a new problem comes up. is it possible that my ViewModel First + CreationPolicy.Shared approach make using the IVisualStateManager not working?

Coordinator
Jul 3, 2010 at 8:05 AM
Yes, if you have CreationPolicy.Shared you cannot use IVisualStateManager... the reason is that the IVisualStateManager is a IContextAware service, MEFedMVVM is looking at the element you are bound to and hooking the IVisualStateManager to its VisualStates. With CreationPolicy.Shared you would always be looking at the first element you were bound to. Why are you using CreationPolicy.Shared for the ViewModel?
Jul 5, 2010 at 6:19 AM

hi, i have ViewModel First approach and so using CreationPolicy.Shared fit in very good :)

with the cinch GotoStateCommand i found a solution for this now :). my viewmodels now implement an interface.

public interface IViewLoadedAction
    {
        /// <summary>
        /// Methode wird aufgerufen wenn UserControl geladen ist.
        /// </summary>
        void RunActionAfterViewLoaded();
    }

and i wrote a simple behaviour for usercontrols witch run this method on Loaded Event as long as the dateContext ViewModel has implement IViewLoadedAction.

maybe not a perfect solution but it works :) but thanks for diggin in my problem.

 

Aug 3, 2010 at 10:45 PM

I have the same problem but i don't have CreationPolicy.Shared.

Coordinator
Aug 4, 2010 at 7:24 AM

Sorry with CreationPolicy.Shared you cannot make use of IVisualStateManager.

Coordinator
Aug 4, 2010 at 7:26 AM

if you want for CreationPolicy.Shared ViewModels instead of using IVisualStateManager you can use this attached behaviour

http://marlongrech.wordpress.com/2010/01/25/working-with-the-wpf-vsm-in-an-mvvm-friendly-manner/

Aug 10, 2010 at 7:12 AM

Hi Marlon,

It seems that currently one can't use a Window with VisualStateManager when designing with Blend, because the default implementation tries to attach to a child of a UserControl. I changed line 60 in DefaultVisualStateManagerInvoker.cs from

// if not then check if they are in the content (This is what Blend does, the Visual States are defined in the first element)
var contentControlRoot = root as UserControl;

to

var contentControlRoot = root as ContentControl;

Now it attaches correctly even when using VisualStateManager with a Window (a ContentControl) designed in Blend.

- Jussi
             

Coordinator
Aug 10, 2010 at 7:27 AM
was this in WPF? I think the same code would not work in WPF.... Will check it out and fix the issue.... thanks for reporting it !!
Aug 10, 2010 at 7:38 AM

Yes, this is in WPF and is working just fine for me. I didn't check how it affects Silverlight, so I don't actually know about that.

Coordinator
Aug 10, 2010 at 7:42 AM
thanks for this... i have a fix for WPF(using your code) and for SL... yet when I am trying to checkin I get an issue with codeplex SVN :S Server sent unexpected return value (409 Conflict) in response to CHECKOUT contacted Codeplex will try to resolve this and commit asap. Again Thanks for the help and support !
Aug 10, 2010 at 7:43 AM
Edited Aug 10, 2010 at 7:53 AM

I just realized that in Silverlight UserControl doesn't derive from ContentControl so I guess you need to add #if #else #endif block to have implementations for both WPF and Silverlight.