tags:

views:

795

answers:

4

Here's the scenario:

I have the following user control, the idea is that it's view model should be able to signal to the view that it needs to "Activate the Glow", thereby playing the Storyboard.

<UserControl x:Class="View.UnitView"  ... >
   ...
    <Storyboard x:Key="ActivateGlow">
       ...
    </Storyboard>
    ...
    <!-- INVALID BINDING! Not Dependancy Object-->
    <EventTrigger RoutedEvent="{Binding OnActivateGlow}"> 
       <BeginStoryboard Storyboard="{StaticResource ActivateGlow}"/>
    </EventTrigger>
</UserControl>

in the codebehind for UnitView, I have:

public event EventHandler ActivateGlow;

and as is pretty normal in MVVM, I have the following DataTemplate for UnitViewModel:

<DataTemplate DataType="{x:Type vm:UnitViewModel}">
    <vw:UnitView d:DesignWidth="150" d:DesignHeight="100" />
</DataTemplate>

The ulitmate question is, how can I set up something so that the viewmodel can fire the OnActivateGlow event?

A: 

I believe you would have to bind to a RoutedEvent instance, not a CLR event.

I haven't tried it, but something like this should work:

public class UnitView
{
    public static readonly RoutedEvent ActivateGlowEvent
        = EventManager.RegisterRoutedEvent(
              "ActivateGlow", RoutingStrategy.Bubble,
              typeof(RoutedEventHandler), typeof(UnitView)
          );

    public void RaiseActivateGlowEvent()
    {
        RaiseEvent(new RoutedEventArgs(ActivateGlowEvent));
    }
}
Drew Noakes
okay that answers HALF of my question, now how do I get the view model to trigger ActivateGlow?
Firoso
+2  A: 

Update: Firoso, as mentioned in the comments you should be able to (I think - i.e. untested) be able to use the blend behavior components to cover your requirement.

In addition to downloading and installing the SDK. Get a copy of the expression blend samples library (you'll need to click on Downloads from the following link): Expression Blend samples

This library contains a prebuilt trigger called 'DataEventTrigger' which you can use to trigger actions in response to an event declared on your viewmodel.

The blend SDK already has (from what I can tell) the other piece of the puzzle - it already includes an action which allows you to control storyboards. The name of this action is 'ControlStoryboardAction'.

You should end up with some xaml which looks like this:

    <i:Interaction.Triggers>
        <samples:DataEventTrigger EventName="YourEvent">
            <im:ControlStoryboardAction Storyboard="{StaticResource Storyboard1}" 
                   ControlStoryboardOption="Play"/>
        </samples:DataEventTrigger>
    </i:Interaction.Triggers>

Replace 'YourEvent' with the name of the event you have defined on your viewmodel, and replace 'Storyboard1' with the name of your storyboard. Of course the names will have to match exactly.

Here are the xaml namespace definitions used:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
xmlns:im="clr-namespace:Microsoft.Expression.Interactivity.Media;assembly=Microsoft.Expression.Interactions"
xmlns:samples="clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity"

Original post, before edit:

Suggest you look into Expression Blend Behaviors:

information

Blend SDK

video on behaviors

Phil
not sure this is relevant, this is all view binding to view elements as far as I can tell, it doesn't really reflect on the view model.
Firoso
Well.. as I understood it, your question revolved around getting the viewmodel to trigger some action on the view? You can do this kind of thing with blend behaviors. I'm not sure if you would model it the way you are - with an event. But you can do things like raise an event on your viewmodel, intercept this on the view, and then perform an action in response to the event. So, in that case, you would raise a 'requestglow' event on the VM, intercept it on your view, and perform a beginstoryboard action. Behaviors are all about enabling interactions between VM and view without codebehind
Phil
Here's a video where they demo some of the capabilities of blend behaviors: http://channel9.msdn.com/shows/toolshed/Tool-Shed-Tooltip-27-Expression-Blend-3-Behaviors/BTW, I would go as far as to say, if you're using MVVM, you really should take a look at behaviors, even if you don't end up using it for your current requirement. It's a big deal for MVVM!
Phil
okay, I've looked at behaviors a bit now, what's the best way to tie a behavior to an MVVM fired CLR event?
Firoso
firoso, take a look at this page: http://expressionblend.codeplex.com/It contains a library of blend behaviors. It has a trigger called 'DataEventTrigger' which allows you to trigger an action when an event occurs on the object bound to your datacontext.
Phil
I'm not sure what action to use, but you can always write your own actions.
Phil
firoso, I'm doing a bit more searching around, and it appears that there's an action named 'StoryboardAction' built into the blend SDK library. I haven't checked it out, but if it is suitable, together with the trigger I previously mentioned, it may do the job for you.
Phil
if not, I can DO custom actions... Looks like I just need to learn VSM stuff now, thank you!
Firoso
cool, glad to be of help ;) There sure is some cool stuff coming out from MS. VSM is also on my to-do list. So much stuff to learn!
Phil
Wow, thanks, Phil, if you want some karma points, just add link to this answer to my unanswered question on same topic :)) http://stackoverflow.com/questions/1894329/wpf-how-to-signal-an-event-from-viewmodel-to-view-without-code-in-codebehind
Tomáš Kafka
Thanks, Tomas, will do! Karma points much appreciated ;)
Phil
BTW, Tomas, I have some better answers for at least a couple of your MVVM related questions that I see you've posted ;) When I've got some time I can post these also.
Phil
A: 

One way I found to resolve this is to use a data trigger on a DataTemplate that contains the above control... probably not the best way to do this however. I'm still open to better ideas.

Firoso
+2  A: 

You can also put a boolean IsGlowing property on your viewmodel and use datatriggers in your style

<Rectangle.Style>  
    <Style TargetType="{x:Type Rectangle}">  
        <Style.Triggers>  
            <DataTrigger Binding="{Binding Path=IsGlowing}" Value="True">  
                <DataTrigger.EnterActions>  
                    <BeginStoryboard>  
                        <Storyboard>  
                            ...  
                        </Storyboard>  
                    </BeginStoryboard>  
                </DataTrigger.EnterActions>  
            </DataTrigger>  
        </Style.Triggers>  
    </Style>  
</Rectangle.Style>  
qntmfred