Picking up after part 1, where our artistically challenged software developer just finished writing a view model. We will continue with the user interface designer where he will
- Create a beautiful and eye catching user interface.
- Use Blend Behaviors to handle button click events
- Define a special behavior that passes a property to the view model
The UI artist is using Expression Blend. After several months of designing he ends up with this:
With a layout like this:
Our artist did not graduate at the top of his/her class.
Wiring Up Commands on the View
You need to first attach a DataContext to the UserControl. A DataContext will help the application bind to the commands we created and it is even helpful at design time when setting the bindings. You want to set the DataContext at the highest level you can so that all the child controls will have access to the DataContext as well. Select the [UserControl] or LayoutRoot in your layout and create a new DataContext from the properties window. You will see your view model (VideoPlayerViewModel) in the list of choices. This class was created in part one of this post. Now we can reference those commands we created in the model.
To allow those commands to be executed you need to add a behavior to the element you want to make the command call. Click the PlayButton and add a behavior asset called
InvokeCommandAction. Notice that it will become a child of the PlayButton.
Click on the command in your layout. Set the EventName that will invoke the command to be
Click. Now all you need to tell it is what command to invoke. Click the tiny box on the right of the command property and click Data Binding. The Data Context tab reveals the relevant properties you can bind to. In this case you want to bind to the
PlayCommand on your model. You can just as easily edit commands straight through Xaml if you prefer. Repeat these steps for your Pause and Stop buttons.
Now you have some great buttons but no media element source to control. The last command to hook up to the view is the
MediaOpenedCommand. As you would expect, it is done the same way as the buttons only with a different EventName.
Select your MediaElement in the layout and add an
InvokeCommandAction so that it is a child of the MediaElement. Change the EventName to be
MediaOpened and set the command to be
MediaOpenedCommand just as you did with the buttons. This just means as soon as the MediaElement has successfully loaded the source defined, invoke this action.
This command will have a catch though. If you remember, our developer is expecting us to provide our MediaElement so that it knows how to control the video. We can send this information to the model with this
MediaOpenedCommand. You need to send the loaded media element as parameter. In the
InvokeCommandAction properties, click the show advanced properties arrow in Common Properties to get more info. Click the tiny advanced options box to the right of the
CommandParameter property. This time, we want to bind using the element tab and select the MediaElement in your view. Not a property on the MediaElement, just the MediaElement object.
Once the command parameter is defined you are finished.
You have just made the worst video player ever created, but you can feel good that you did it without writing any code behind and you were able to separate concerns between the developer and the user interface designer.