Advice about handling visual states

Sep 5, 2010 at 10:03 AM

Hello,

I have been battling with setting up visual states in my application, and I would really use some advice...

First, here is my scenario. I have a list of objects (UI models) which represents tasks in my MainViewModel. They have 2 "state groups": they can be "up-to-date", "waiting for input" or "waiting for work" on one hand, "active" or "inactive" on the other hand. This list is bound to a ListBox. When the user double clicks on a task, it opens a tab with the task details. It doesn't seem too fancy, but I'm new to visual states and I think I got confused somewhere...

As far as I understood, I cannot use visual states or triggers in a DataTemplate, so I move all my XAML to a UserControl. I am really bad at unit testing (I never know what to test or how), but I want to do it the right way (or at least try), so I decided to use IVSM. But, I am working with UI models in this list, so I think it is a bad idea to have services or states in UI models, it belongs to view models as far as I understood it, right? So I probably need to encapsulate my UI models in specific view models for this list. This view model will only be responsible for handling states, am I correct?

I have been circling since yesterday, so I want to know if I'm headed in the right direction here...

Thanks for the help.

Damien

Coordinator
Sep 6, 2010 at 6:21 AM

Triggers CAN totally be used in DataTemplates/Styles. So can VisualStates.

And yeah you want it so the VisualState to go to is in your ViewModel using the IVSM service, or use some properties of your VM if using triggers.

Sep 7, 2010 at 1:48 PM
Edited Sep 7, 2010 at 1:53 PM

Good news that VisualStates can be used in DataTemplates. I had some issues with them, googled and found some articles stating that VisualStates cannot be used inside DataTemplates and recommending to use UserControls. But maybe my issue was somewhere else. I'll definitely try that, thank you.

As for my "architecture", can you validate the design I have came up with? It does sound a little bit "too much" for a small need like this...

I have my Task class: it represents the data object, which is actually based on EF. As I think it is not so good an idea to have EF stuff in my UI (am I right?), I have created a TaskUiModel class which is basically a transposition of my Task for my UI (it does inherit from Cinch's ViewModelBase).
When my application starts, a MainWindowViewModel is created and it loads a list of tasks which is displayed in a ListBox. The data service returns a List<Task>. Each Task is transformed in a TaskUiModel, and then encapsulated in a view-model (named TaskListItemViewModel), so as to use the IVSM service.
When the user double-clicks on a task in the ListBox (actually on a TaskListItemViewModel), I want to create a new tab. To do so, I retrieve the TaskUiModel from the TaskListItemViewModel and add a new WorkspaceData, passing this object as the DataValue. The WorkspaceData, in turn, will create a new view-model, named TaskTabViewModel.

What do you think about it? Does it sound "valid" to you?

Damien

Coordinator
Sep 7, 2010 at 3:27 PM

I knew Visual States could be used, as for your architecture, I just don't have time to assist right now sorry.

Oct 6, 2010 at 7:15 PM

Hello Sacha,

I have been busy refactoring my code and I have just tried what this thread is about recently. As far as Visual States and Triggers are concerned, they indeed seem to work well inside Data Templates, I must have done something wrong at the time.

But now I am having trouble with the VisualStateManagerService. Here is what I am trying to do: I have a TaskListViewModel which holds a list of tasks as a DispatcherNotifiedObservableCollection<TaskViewModel>. In my TaskListView, I bind this tasks to the ItemSource of a ListBox and I use a DataTemplate to display my TaskViewModels. Inside this data template, I have set up visual state groups and visual states. As you might have guessed, I am trying to control them with a VisualStateManagerService inside my TaskViewModel.

The problem is (I think) that my TaskViewModels are created by my TaskListViewModel. So what I do is add an IVSM in my TaskListViewModel (using the ImportingConstructor attribute) and pass it to all the TaskViewModels that I create inside. When I start my application, nothing happens, no state is displayed. I have seen in Cinch code that VSMService is not meant to be shared and that when I debug, IsInitialized is set to false on the VSMService. I am sure I am doing it wrong, but I really don't know how to do it. Can you give me some pointers?

Thanks for your help,

Damien

Coordinator
Oct 7, 2010 at 6:45 AM

 

I see what you are after. But believe it or not I rarely use VisualStates, I much prefer triggers. The only thing I like about VSM is Easing functions, but anyway.....For you problem, I think Marlons MeffedMVVM code has a solution for this (and as such so does Cinch).

He has a special interface called IDataContextAware, which he uses to inject services into ViewModels that have their DataContext set via some other binding (like you would in your list example). I think best bet on this one is to ask Marlon this question using his MefedMVVM codeplex forum, and refer back to this forum entry.

Oct 8, 2010 at 11:57 AM

Hi Sacha,

I was going for triggers at the beginning too, but I have one issue that I can't manage to solve. To be honest, if I can manage to solve it, I'd rather stick to triggers as well. If I can't I'll look into IDataContextAware.

My problem is the following one: I can't manage to go to the correct state on initialisation. The triggers only get activated when a property changes AFTER initialisation. I get the logic behind it, but I really don't know how to manually trigger the correct visual state when loading. How do you do that?

Damien

Coordinator
Oct 9, 2010 at 6:50 AM

To be honest I do not know how to fix your issue....As I say I work in WPF, and cant stand SL really. Might be worth asking Marlon

Oct 9, 2010 at 1:51 PM

Actually, I'm using WPF as well, I have never used SL yet. It is not the first time I read that you cannot stand SL, I really wonder why (not to criticize or anything, I just think it could be an interesting insight).

Damien

Coordinator
Oct 10, 2010 at 6:29 PM

OK for a start, I feel its about 400 years to late, its just flash with hindsight, its still a plugin that runs in sandbox, I did Flash up to AS3, as SL it not that different truth be told. And as for it being same as WPF, it really is not, it lacks so much stuff that WPF can do.

 

If I do web stuff, I am going with JQuery/HTML 5 and ASP MVC all the way. One thing SL does have it cross platform, but that is just because it does OOB, but that means full trust, which means might as well use best tool for that platform, be that WPF, Java, C++ or whatever. I mean if its running OOB and you use Windows features you are tied to windows, so why not use WPF proper, instead of a less able SL offering.

Pick the right tool for the job, and right now for me, SL is not right for any job....but that is just me.

 

 

Oct 10, 2010 at 8:41 PM

Sacha,

I see your point and I tend to agree with you. For me, SL is just Microsoft's Flash. Clearly, if someone knows HTML/Javascript, it is much more "universal" to use that than SL. I just don't know how much more work it will require to use ASP/HTML/jQuery instead of SL (as I am more a WinForms and WPF guy than a web guy). But I'll think I'll give it a try with WP7 as it seems to be fun.

Damien

Coordinator
Oct 11, 2010 at 9:00 AM

Yeah clearly I am more of a Winforms/WPF chap, than Web, but I just think you should pick the right thing for the job. For example at work we use Crm from Microsoft, which is a browser based app, which will only work in IE6. So what is then point of that, that should have been a click once windows forms or WPF app. And I think OOB with SL will make people make the same mistakes

Oct 11, 2010 at 10:55 AM

IE6-only website seems even more stupid than OOB SL! Anyway, thanks for sharing your opinion on the matter, it is nice to hear an experienced opinion. At my work, we are just starting to move forward slowly, but most of our apps are still developped using .Net 2.0, even though we started to use VS 2010. It is very hard to make them consider new technologies, let alone ask them about an interesting opinion about them...

Coordinator
Oct 11, 2010 at 12:38 PM

Don't get me wrong you do have a point SL is quick to develop in, but I just prefer WPF