Compartilhar via


Bind media to playback controls

Building a basic media viewer with controls for volume, balance and interacting with the playback

Contents

Overview
Creating the application
       Task 1: Creating the components for the PlayPause button
       Task 2: Set up the states and triggers on PlayPause
       Task 3: Add the media, and define how PlayPause interacts with it
       Task 4: Add the Volume and Balance controls
       Task 5: Databind the VolumeLabel

Overview

In this tutorial, you will build a basic-looking but functional video player entirely within Microsoft® Expression™ Interactive Designer. You will use templates and triggers to create a custom control that displays the state of the video playback and other parameters. You will explore some of Interactive Designer's path-editing controls, including learning how to interact with the individual vertices of a shape by changing a rectangle into a triangle. You will also use data binding to create controls to interact with the media file. Finally, you will create and use a value converter to modify how a data-bound relationship between two elements is displayed graphically.

The MediaControl will display the media in the center of the application when the PlayPause button (the blue button in the center) is clicked. When the button is clicked, it will change from the 'Play' icon to the 'Pause' icon, and clicking it again will pause the video on the current frame. The BalanceControl on the left will adjust the balance between the left and right speakers, and the VolumeControl on the right will increase or decrease the volume. The VolumeControl also shows the volume in a more conventional 0-10 value, which users are familiar with, instead of the 0.0-1.0 format that Windows Presentation Foundation (WPF) uses.

This tutorial serves as a starting point for playing and interacting with media in WPF applications. Additional controls, such as 'seeking' to a particular point in the media, or allowing the user to choose the media file to display, may be covered in later tutorials or they can be exercises for the reader.

TipAs you work in Interactive Designer, your changes take place in memory and not on your hard drive, so be sure to save early and often.

TipIf a palette is collapsed, expand it by clicking Expand on its title bar or simply double-click the title bar.

Creating the application

Task 1: Creating the components for the PlayPause button

  1. On the File menu, point to New and then click Project. The Create New Project dialog box is displayed. Select the Standard Application (.exe) project type and name the project EIDMediaViewer. Set Language to whatever language you like. We will be writing a small amount of code later on, but the code will be provided in Visual Basic and C# alternatives. Choose the language you're more comfortable with, should you wish to do more experimentation on your own.

    NoteFor convenience, a newly-created project is initially stored in a temporary folder. If there are unsaved changes when you close Interactive Designer then you will be prompted to save the new project in a permanent location.

  2. In the Library palette (View | Library), choose the PresentationFramework library from the drop-down list and then select CheckBox from the list of element names (tip: click in the list and press C until CheckBox is selected). The pointer will turn into a crosshair. Draw a CheckBox by clicking on the artboard and dragging a bounding box inside the scene. Release the mouse button when the bounding box is the size, and in the position, that you want the play/pause button to be.

    You have a choice how you create a new element. You can draw the element freehand as you did in the previous step. Alternatively, you can simply double-click an element name in the Library palette to have Interactive Designer insert the new element with a default size and layout.

  3. The CheckBox is named CheckBox by default, but its purpose will be clearer if you rename it PlayPause. An element has to be selected before it can be renamed. Look in the structure view in the Timeline palette (View | Timeline) and notice how the background behind the CheckBox entry indicates that it is already selected. This is a workflow convenience for newly-created elements. So now just click the CheckBox entry in the structure view and wait a moment for the name to become editable. Type PlayPause and press ENTER.

    Newly-created elements are automatically selected in the Timeline palette’s structure view. In other cases you can select the element by expanding the tree if necessary and then clicking the element’s name.

    Another way to rename an element is first to select it and then use the Properties palette (View | Properties). You can edit the Name of the element either in the large text box at the top of the palette or in the property grid (within the Misc category if you have Categorized the properties). The property grid lists property names in its first column and corresponding values in the second column. In either of these places, edit the text and then press ENTER or TAB when you’re done.

    An element can be selected by clicking its name in the structure view. Before you click to select an element on the artboard, or to perform certain other artboard tasks with it, you need first to click Selection  in the Tools palette (View | Tools). As a scene develops in complexity, using the structure view to select is recommended.

  4. Right-click PlayPause and create a new template (Edit Template | Create Empty Template... ). This will instruct Expression to create an empty template for our control, but still to treat it fundamentally as a CheckBox. We're going to create Triggers in our template to change how the control looks based on its state. The state in this case being whether or not the control is checked.

    We could edit a copy of the template instead, and this would leave the triggers that normally exist on the CheckBox in place for us. But, since we're only interested in a few of these, it makes more sense to begin with an empty template.

  5. The Create ControlTemplate Resource dialog is displayed. By creating a new template, we are creating a new re-usable resource. The key of any resource is the name by which it is uniquely identified within its resource dictionary.

    In Key, type PlayPauseTemplate.

    The Define in: option indicates which resource dictionary to define your new template in. A resource dictionary can be defined at a point on a range from very local to very global and this determines the scope in which the resource is visible and available for re-use. If we wanted to use the same control on multiple scenes in our application, we'd define our template in the Application Root. But, since we're only using it on this scene, leave the Define in: option as This document.

    TargetType is the type of element to which this template will apply. In this case we want the template to apply to any CheckBox so leave the setting as it is.

    Press OK.

  6. Notice now that the timeline has changed to indicate that we're editing a template. In this mode, work done on the artboard will apply to the PlayPauseTemplate. If you inadvertently exit this mode and you wish to return to editing the template then right-click PlayPause, point to Edit Template, and then click Edit Template.

    The next steps are to build up a new template for the CheckBox which we named PlayPause.

  7. CheckBoxes are designed to have a single element of content within them. Since we want to have multiple visual elements in our control, add a Canvas to the control to put them in. This is done most easily by double-clicking Canvas in the Library palette, instead of dragging it out. When created by double-clicking, the Canvas will take up the entire space of our template. The Canvas is a control in the PresentationFramework.

    Let's rename the new canvas PlayPauseTemplateRoot. This is done the same way we renamed the CheckBox earlier in the tutorial.

  8. Double-Click the PlayPauseTemplateRoot in the timeline. This will set it as the activated element, so that what we subsequently draw or add to the art-board will be created inside it. Unless we activate PlayPauseTemplateRoot, the root of the template (named Template in the timeline) will remain activated and any new element we create will become its child and will replace the Canvas.

    When it is activated, PlayPauseTemplateRoot will appear with a yellow outline in the timeline.

  9. Add an ellipse to PlayPauseTemplateRoot. Select the Ellipse tool , and draw a new ellipse inside the canvas. You can hold down SHIFT to constrain the ellipse to be a perfect circle.

  10. The basic, empty ellipse isn't too exciting, so let's change the appearance of it. Bring up the Appearance palette if it's not already visible (View | Appearance).

    First, let's use a Radial Gradient. Of course, you can choose whatever appearance you like: this is simply one way to do it. Click Radial Gradient Brush Note from the brush editor control.

    When editing a radial gradient, you can create new gradient stops, move gradient stops, and reposition them with the gradient editor. We're not going to cover everything you can do with the gradient editor and Appearance palette in this tutorial. Change the first gradient stop to a dark blue, and the second gradient stop to a lighter blue.

  11. Now, we're going to design the Play and Pause symbols. First, we'll create the Pause symbol.

    If you like, you can zoom into the template. Select PlayPauseTemplateRoot in the timeline, drop down the Zoom list (lower-left corner of the art-board), and select Fit To Screen. This will cause the PlayPauseTemplateRoot to take up the entire view in our artboard. Now the ellipse is much larger, and easier to work with.

    When you're done, you can reset the view to 100%, to see how everything looks at normal scale.

  12. A Pause symbol consists of two vertical bars. Now, inside the ellipse - to the left of center - draw a tall, thin Rectangle. This is the left bar of our Pause symbol. For ease later, let's rename it PauseLeft.

    To color the rectangle solid black, select Solid Color Brush Note in the Appearance palette, and set the color to black.

  13. Verify that PlayPauseTemplateRoot is still the activated element. Then select PauseLeft and Copy and Paste it. You can do this either with Edit | Copy and Edit | Paste, or with CTRL+C and CTRL+V.

    In the scene, it looks like nothing happened. When you copy an element, all of the properties of that element, including its position, are duplicated. The new rectangle is exactly on top of the original rectangle. You can see the new element by looking in the timeline, and observing that PauseLeft_Copy has been created.

    Rename PauseLeft_Copy to PauseRight.

  14. We want to drag the new rectangle to the right of the original without changing its vertical position. To constrain movement horizontally or vertically, you can hold down SHIFT either before or during the drag operation. With the Selection tool, and holding down SHIFT, drag the rectangle named PauseRight to the right of the rectangle named PauseLeft and drop it when you're happy with its position.

  15. Since these two rectangles together constitute the Pause symbol, we can group them to make them easier to work with. Select both rectangles by selecting one of them, and holding down SHIFT while selecting the other. You can group either from the Arrange | Group command, or simply press CTRL+G. This combines the two elements into a single element that can be worked with as a unit.

    In the timeline, you'll see that a new element has appeared, named Group. If you expand it, you'll see that PauseLeft and PauseRight are the two children of it. Rename Group to Pause.

    You can also move Pause around, to get it positioned exactly where you want it. When Pause is resized, all the elements within it will be resized proportionally.

    You can also double-click Pause in the timeline, to make it the activated container. Once this is done, you can go back into PauseLeft and PauseRight to reposition them until you get your control exactly how you want it. If you activate Pause, when you're done working with it, remember to activate PlayPauseTemplateRoot before continuing.

  16. Now, with Pause selected, go to the Properties palette and find the Visibility property (It's in the Misc category, if you're using the Categorized view). Set Visibility to Hidden.

    We are hiding the Pause symbol now so that we can draw the Play symbol. Later in the tutorial we'll see how to switch the visibility of the two symbols so that they show at the appropriate time.

  17. The next step is the Play symbol. Make sure the PlayPauseTemplateRoot is still activated (it should have a yellow border around it). Draw a rectangle in the center of the ellipse.

    The rectangle is named Rectangle, but let's rename it to Play.

  18. Since we don't want a rectangle, but a triangle, we're going to edit the geometry of the rectangle by turning it into a path. This technique can be used with any of the built-in Expression Interactive Designer shapes.

    Start by selecting the rectangle and converting it to a Path. Use the Tools | Convert To Path command. The rectangle has been turned into a path and it has kept its shape. It has been moved into the top-left corner of the template but we can reposition it later. Now we can edit the path so that it has any shape we like.

  19. A rectangle has four vertices, and a triangle has three. The first step is to delete one of the vertices. Select the Pen tool .

    When you select the Pen tool, the adorners on our rectangle change. These are the individual points of the geometry of our rectangle. We want to delete one of these, so place the mouse cursor over the lower right vertex until the mouse pointer changes to a pen icon with a minus sign beside it. This cursor indicates that the vertex under the pointer will be deleted. When you see this, left-click to delete the vertex.

  20. Next, select the Subselection tool . With this tool, we can move individual vertices. Left-click on the upper right vertex, and drag it down to the middle of the right edge of our bounding box. You can use SHIFT to constrain the movement of the vertex to vertical only. You'll get a live preview of how the shape will look as you drag. Release the mouse button, and the rectangle has now been changed into a triangle.

  21. With the Selection tool, position the triangle in the center of our button, to get it right where we want it. Then, as we did with the Pause button, set the Visibility in the property palette to Hidden.

Task 2: Set up the states and triggers on PlayPause

Now we have all the components for our PlayPause control. You can make it look like a play button by making the Play element visible, and you can make it look like a pause button by making the Pause group visible. The next step, is to explain to WPF when it should look like each of these.

To do this, we're going to define States on our template. Each State will have Triggers which will be evaluated while the application is running, and whenever all the Triggers are true, it will cause the button to look the way we specify. The Checked propety on PlayPause will indicate whether the video is playing or not. When the PlayPause is Checked, the video is playing. When it's Unchecked, the video will be paused.

So, logically, when our control is checked and the video is playing, we want it to look like a pause button. When the control is unchecked, and the video is not playing, we want it to look like a play button.

  1. Expression should still be editing the Template for the PlayPauseTemplate. If not, right click PlayPause in the timeline or on the scene, and select Edit Template | Edit Template.

  2. In the timeline, we need to add a State. Click Create New State Note. The first thing to notice is that there's a new tab in the timeline. At the moment, it says "[No triggers]", which means that WPF doesn't know when the State is active. We need to add Triggers that define the State. A State can have any number of Triggers, but in this case, we only need one.

  3. If the Timeline Properties palette is not visible, bring it up with View | Timeline Properties. This palette has two tabs. Make sure that General is selected.

  4. Click Add on the Timeline Properties palette.

  5. A row, representing a Trigger is now added, and this is where we specify the condition for the State. The left side is the property or field on the control that we're interested in, and the right side is the value we want to compare against. For now, we need to know if the control is checked or not, which is determined by the IsChecked property on PlayPause.

    So, in the left field, type IsChecked. When you press ENTER, a couple things happen. First, Expression Interactive Designer recognizes that IsChecked is a property that can be either true or false, so it chooses False as a default value.

    Additionally, the State is renamed "!IsChecked". The ! symbol indicates "Not", so in this case, the state's name means "Not IsChecked". When this State is selected in the timeline, any changes will only be displayed when PlayPause is not checked.

  6. When PlayPause is not checked, the video is not playing. This means we want the Play element visible. Select Play in the timeline.

    In the property palette, set Visibility to Visible.

    So, what we've specified now, is that when the IsChecked property on PlayPause is False, we want Play visible, and everything else in the default state.In WPF terms, what we've said is that the !IsChecked Stateis active when the IsChecked property on PlayPause is false, and when it is active, the Visibility of the Play element should be True.

    Next, we want to define the IsChecked state, which is active when the IsChecked property on PlayPause is true, and when active, the Visibility of the Pause group should be True.

  7. Now, click Add State Note again.

  8. Add a Trigger, but this time, specify that IsChecked is True. This will cause the state to be named IsChecked (notice that the ! character is not there).

  9. Just as we did with Play, set the Visibility on Pause to be Visible.

  10. We have now created our control. Run the application, and look what happens when you click the control. It should switch from looking like a Play button to a Pause button and back.

    Our PlayPause control is complete.

Task 3: Add the media, and define how PlayPause interacts with it

For this tutorial, our application is going to have the media element in the project itself. This sample application could be expanded to allow the user to select a media source (a different video clip), but for purposes of this tutorial, we're going to make it so the application has a single video to display.

The next step in the tutorial is to add the media, and hook PlayPause up to it.

  1. Expression Interactive Designer needs all the assets your program will use to be explicitly added to the project. Media files are considered assets, so we need to add it to the project.

    Go to Project | Add Existing Item...

  2. A dialog will come up, asking for the location of the item you'd like to work with. Browse to any WMV file on your computer. In the March 2006 CTP, Expression Interactive Designer only supports WMV files, but additional file formats should be supported in future versions.

  3. We need to create a timeline for the media element. By default, Expression will think that when a new media file is added, that you want it to begin playing as soon as the application is started. This means that it will be added to the OnLoaded timeline. Although this is the most common case, it is not the case for this tutorial, so we're going to make a timeline specifically for our media element.

    Click the Create New Timeline Note button. When the dialog comes up to ask for a name, name the timeline MediaTimeline.

  4. Once the asset is added, it should be visible in the Projects palette. Double click on the asset to add it to the scene. Alternatively, with the media file selected, you can Right-Click the media file, and choose Insert Into Scene.

    You'll notice that a new Media Element has been created, with a name that is derived from the name of the media file. In my case, I used Expression.wmv, so the media element is named "expression_wmv". Whatever the media element is named in your scene, rename it MediaElement.

  5. A note at this point, MediaTimeline is currently active. This means that any changes you make to the scene are interpreted as part of MediaTimeline. So, for instance, if you were to resize MediaElement, it will be resized at the beginning of MediaTimeline, not actually on the scene.

    If you need to change the size, position or any properties of any elements, you should switch to the None tab in the timeline first.

  6. If you've changed the current timeline, make sure MediaTimeline is selected again.

    We now need to hook our PlayPause control to MediaTimeline. Bring up the Timeline Properties palette again. If it's not visible, you can find it under View | Timeline Properties.

  7. A few words about timelines. A timeline is always in one of three states. It can be Stopped, which is the default state, Playing or Paused.

    When a timeline is Stopped, nothing can be done with it, except to Begin it. You can't Resume or Pause a Stopped timeline. When you Begin a timeline, it will always begin playing at the beginning, and the timeline is logically considered to be Playing.

    When a timeline is Playing, you can do two things with it. Pausing a Playing timeline will cause it to pause. It will leave the last frame of the media file on screen, and the timeline is now considered Paused. Alternatively, you can End a timeline. This will put the timeline in the Stopped state, and what is displayed varies depending on other properties on the Media Element. Normally, this will be the frame that was displayed when the timeline was ended.

    Finally, when a timeline is Paused, you can either Resume the timeline, where it will begin the timeline again at the point where it was Paused, putting it in the Playing state. Alternatively, you can End the timeline. Ending a Paused timeline works the same way as Ending a timeline when it is Playing.

  8. When our application starts, MediaTimeline will be Stopped. Consider what would happen if we told the PlayPause to Begin MediaTimeline. Then, every time the user hit the Play icon, the media clip would restart at the beginning. This isn't how we want PlayPause to work. We want the play button to Resume MediaTimeline.

    But, we can't Resume the timeline, until it is in the Paused state. And when the application starts, the timeline is Stopped. The solution, in this case, is to Begin the timeline, and immediately Pause it.

    So, in the Timeline Properties palette, we want to add an Event. Make sure the General tab is selected. The panel is the same one we used before to set up the States earlier, but this time, as you can see by the panel, we're editing Events now.

    Three combo boxes appear. From left to right, they indicate the element on the scene that the timeline event is associated with, the event for that element to receive to cause the timeline event to occur, and the action to perform on the timeline.

    Select DocumentRoot in the first combo box, Loaded in the second combo box, and Begin in the third. This is stating that when the DocumentRoot is Loaded, we will Begin MediaTimeline. Expression knows that we want to apply the event to MediaTimeline because that's the timeline that is selected when we specified the event.

    Whenever an application starts, all of the Loaded events on the DocumentRoot happen immediately. So, logically, by doing this, MediaTimeline begins immediately.

  9. If you run the application now, you'll see that the media starts playing immediately. However, this is not what we want. We'll add a second event in the Timeline Properties palette. This time, select DocumentRoot and Loaded again, but in the third combo box, select Pause.

    When multiple events occur at the same time, they are always executed in order from top to bottom. Keep in mind what we discussed before, and look at what we've just told our application to do. First, we Begin MediaTimeline, which puts it into the state where we can Pause or End it. Then, we Pause the timeline. So, the first frame of our media is displayed, but it's Paused, so we can Resume then Pause it at will.

  10. Now, with our MediaTimeline ready to be Resumed and Paused, we can hook up PlayPause. Select PlayPause , and hit Add in the Timeline Properties palette again.

    This time, PlayPause is put into the left box for us automatically, since it's selected. In the middle box, select Checked. Finally, in the last box, select Resume. When PlayPause is not checked, we decided that this means that the media is not playing. So, when we Check the button, we're switching from the state where the media is not playing to when it is playing. So, we Resume the timeline.

    Similarly, we need to add the event for when PlayPause is Unchecked. In this case, we want to Pause the timeline.

  11. Run your application now. If everything has been done correctly, you should now be able to click the button that has the Play icon, to cause the media to start playing, and Pause the video by clicking the button again.

    The most common mistake, if your application isn't working correctly, is to check the events. Remember that you need to Begin then Pause the video when the DocumentRoot gets Loaded, then you need to Pause and Resume the timeline with PlayPause. You should never be Ending the timeline, and the only time you Begin it, is when the DocumentRoot is Loaded.

Task 4: Add the Volume and Balance controls

Our application now shows the video, and allows the user to control when it's playing and when it isn't, but we want some more control for the user. In this step, we're going to allow the user to adjust the volume and balance. The BalanceControl is an analog control, which means that the user can nudge it however they want. But our VolumeControl will be a digital control, which has 11 specific settings, numbered from 0 to 10. The user can't set the control between two ticks. Both controls are sliders, but have different behaviors, based on the properties we set.

Additionally, we're going to display the volume to the user, but we will use a Value Converter to show the value to the user in the manner we wish, instead of the way the Windows Presentation Framework uses it.

  1. First, make sure you're not editing any templates or have any timelines selected.

    If you're editing a template, click Return Scope To Root Note. Do this until DocumentRoot is the top item displayed in the timeline.

    Then, make sure the None tab is selected in the timeline. The Playhead and the red timing ruler should not be visible.

  2. We'll start with BalanceControl, since it's the simpler of the two controls. Locate the Slider control in the Library Palette. (View | Library if it's not already visible). The Slider is in the PresentationFramework assembly.

  3. Drag the Slider out to the left of PlayPause, and rename it BalanceControl.

  4. By default, a Slider is used to represent a floating point number between 0 and 10. Media elements in the Windows Presentation Framework represent audio balance as a floating point number between -1.0 and +1.0, where -1.0 is exclusively the left speaker and +1.0 is exclusively the right.

    In other words, we need to set properties on  BalanceControl, so that it can interact with the Media element in a way that the Windows Presentation Framework understands.Open the Properties palette (View | Properties if it's not already visible).

  5. First, find the Minimum and Maximum properties. Set the Minimum to -1 and the Maximum to 1.

  6. This is the only setting you need to change the the BalanceControl. You can change the SmallChange or LargeChange values, if you expect the user to want to change the value with the keyboard, but for this tutorial, we can leave them alone.

  7. It's always best to label controls, so the user knows their function. Select Label from the Library palette. Labels are also in the PresentationFramework assembly. Create one in the artboard above the BalanceControl. Change the name of the Label to BalanceLabel .

  8. In the Properties palette, find the Content property for the BalanceLabel and set it to Balance.

  9. Finally, you can adjust the location of the BalanceLabel wherever it looks best. Feel free to experiment with other properties on the BalanceLabel, such as the FontFamily or FontSize to get the appearance more to your liking.

  10. Now, drag out another Slider on the right side of the PlayPause button, and name this one VolumeControl.

  11. Just as we did with BalanceControl, we need to change the Minimum and Maximum on VolumeControl to be in a format that the Volume property on the media element understands. The Volume in the Windows Presentation Framework is expressed as a floating point number between 0 and 1.

    So, set the Minimum and Maximum on VolumeControl to 0 and 1 respectively.

  12. For the VolumeControl, we want to supply some tick marks on to make it easier for users to see where the values are. The TickFrequency property tells VolumeControl how to display the ticks. The first tick will always be placed at the Minimum value, and then another tick will be placed every TickFrequency thereafter. There will also be a tick placed at the Maximum value, even if a tick wouldn't normally be put there.

    So, consider if we set TickFrequency to 0.1. We would get a tick at 0, 0.1, 0.2, 0.3, and so on... This would create 11 ticks total. And if we think about it, for VolumeControl, we want 11 ticks, one for each value between 0 and 10. So, set the TickFrequency to 0.1.

    Finally, by default, Sliders don't display the ticks. We need to set the TickPlacement property. Any value other then None will show the ticks, and it's purely aesthetic whether we put the ticks above or below the slider. For this tutorial, I chose TopLeft, but feel free to use whichever setting you like best.

  13. If you test the application now, you'll find that VolumeControl can go to any position, including between the ticks. For BalanceControl, this is fine, where we might want to the user to have a more Analog experience, but, for this tutorial, we're going to confine the user to only the ticks on the VolumeControl.

    Locate the IsSnapToTickEnabled property in the Properties palette. If you have properties categorized, it's in the Behavior property group. Set this property to True.

    Now, if you test the application, the thumb on the slider will only visit the positions where the tick marks are.

  14. Draw out another Label, this time over the VolumeControl and name it VolumeLabel. You can change the properties on it to match BalanceLabel, but don't worry about the Content of it. The BalanceLabel has a Content that doesn't change, so we can just set it. But, for the VolumeLabel we're going to databind the value, so it changes as we change the VolumeControl.

  15. Now, we've created our controls, but we need to explain to the application how they interact with MediaElement.

    First, select MediaElement.

  16. Locate the Volume property in the Properties palette, and click on it with the right mouse button. A context menu will be displayed, and on that menu, select Databind... .

  17. The Create Data Binding dialog comes up, and on this panel, we'll explain what the relationship between the Volume on the MediaElement and the Value of the VolumeControl is.

    If you look at the top of the dialog, you'll see that we need to specify the source for MediaElement.Volume. The Value property on VolumeControl is that source.

  18. So, select ElementProperty first, since the source is a property on an element. A list of all the scene elements on our scene is displayed on the left, and VolumeControl appears in that list. Select it.

  19. The Value of the VolumeControl is our source, so scroll the Properties list until you find Value and select it. Once this is done, click Finish.

  20. In the same way, we need to databind the Balance on MediaElement to the Value on BalanceControl.

  21. Click Balance in the Properties palette with the right mouse button, and select Databind.. . again. Choose to bind to an Element Property, choose the BalanceControl as the Scene Element, and choose Value as the property. Click Finish to create the binding.

  22. Now test the application. You'll see that you can now change the balance and the volume of your media with the two sliders.

Task 5: Databind the VolumeLabel

By this point, we now have an application that shows a video, allows the user to pause and restart the video, and even lets the user adjust the volume and balance of playback. The last thing we want to do, is change the VolumeLabel to display the current value. However, the VolumeControl recognizes the volume in a different format from how we want to present it to the user.

We're going to use databinding and value converters to not only update the Content of the VolumeLabel as we change the VolumeControl, but also present the value the way we want.

  1. The first step here, is to create the value converter. For this, we're going to write a small amount of code, but it's pretty simple.
    The first thing we need, is a code document to put the value converter in. From the select File | New | Code File. The first time you do this, Expression may take a couple moments to prepare the coding environment. This is normal, and it shouldn't take more then a couple moments.

  2. Once the code editor comes up, replace the contents with the following code. (Make sure you use the correct code piece, if you're using C# or Visual Basic):

    C#

     using System;
    using System.IO;
    using System.Net;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Navigation;
    
    namespace ValueConverterDemo
    {
      public class SliderToVolume: IValueConverter
        {
           public object Convert(object input, Type type, object parameter, CultureInfo cultureInfo)
           {
               double value = System.Convert.ToDouble(input);
              return "Volume: " + Math.Round(value * 10).ToString();
          }
    
           public object ConvertBack(object input, Type type, object parameter, CultureInfo cultureInfo)
           {
               return null;
            }
    
           public SliderToVolume()
         {
           }
       }
    }
    

    Visual Basic

     Imports System
    Imports System.IO
    Imports System.Net
    Imports System.Globalization
    Imports System.Windows
    Imports System.Windows.Controls
    Imports System.Windows.Data
    Imports System.Windows.Media
    Imports System.Windows.Media.Animation
    Imports System.Windows.Navigation
    
    Namespace ValueConverterDemo
    
      Public Class SliderToVolume
         Implements IValueConverter
    
          Public Sub New()
            End Sub
    
         Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As Globalization.CultureInfo) As Object Implements IValueConverter.Convert
                Dim myValue As Double
               myValue = System.Convert.ToDouble(value)
                Return "Volume: " + Math.Round(myValue * 10).ToString
           End Function
    
            Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
                Return String.Empty
         End Function
        End Class
    
    End Namespace
    
  3. You'll need to build your project, so that Sparkle knows about the new Value Converter that you just created. You can do this by pressing CTRL+SHIFT+B, or select Project | Build Project.

  4. We need to databind the Content of the VolumeLabel to the Value of the VolumeControl with our Value Converter. Select the VolumeLabel on the scene.

  5. Click on the Content property with the right mouse button, and select Databind... .

  6. As before, we want our binding source to be an Element Property. So, select that at the top of the Create Data Binding dialog.

  7. Select VolumeControl in the list of Scene Elements.

  8. Select Value in the list of Properties.

  9. Now, we need to specify the Value Converter to use. At the bottom of the dialog, expand More Binding Options... .

  10. As you can see, Expression Interactive Designer is not using a Value Converter. If you open the combo box to specify a Value Converter, our new converter is not displayed. We need to explain where our Value Converter is. Click the ... button.

  11. The Add value converter dialog is presented to us and with it, we specify the Value Converter we want to use. At the top of the list, you should see the EIDMediaViewer. This represents the assembly that contains our entire project, including any code that we've specified. If our Value Converter was in another assembly, say one supplied by a developer, we'd select that assembly instead. However, our Value Converter is defined in our project, so expand the EIDMediaViewer assembly.

  12. Once you expand the assembly, you'll see our ValueConverterDemo namespace and right under it, the SliderToVolume object. Highlight SliderToVolume by clicking on it, and press Ok.

  13. Our ValueConverter is set to SliderToVolume for us, since we just added it. Press Finish, now that the databinding is complete.

  14. Press F5 to test the project. Notice that as you change the VolumeControl, the VolumeLabel updates as we specified in our Value Converter. The "Volume:" string is displayed, and our volume is shown as a number between 0 and 10 instead of 0 and 1.

This completes the tutorial.

Comments

  • Anonymous
    June 09, 2006
    Software Test Engineer, Dante Gagne, takes us through a tutorial of how to bind media to playback...
  • Anonymous
    June 20, 2006
    Up on the Expression blog, a fantastic tutorial that isn't in the docs yet has been posted.  I just...
  • Anonymous
    July 11, 2006
    Through KarstenJ comes this gem of a tutorial in the Expression blog that walks you through building...