Reputation: 3506
To learn WP7 i'm making a simple soundboard application.
This is my code. Please ask if i accidentally left something out in my tries to keep things simple.
MainViewModel contains this collection
public ObservableCollection<SoundViewModel> Sounds { get; private set; }
The soundViewModel contains these properties, they are both notifying any property changes
public string FileName
public string Name
Xaml / View contains a listbox bound to the Sounds collection on the viewmodel
<ListBox x:Name="FirstListBox" Margin="0,0,-12,0" ItemsSource="{Binding Sounds}">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="Play" CommandParameter="{Binding FileName}" Command="{Binding DataContext.PlaySound, ElementName=FirstListBox}" />
<es:Arc x:Name="arc" ..bla bla attributes. />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
When i click the button, the parameter / filename is used to located the file and invoke the following method.
This method is enclosed in a RelayCommand and bound to the button in the datatemplate
private void PlaySound( string filename )
{
Stream stream = TitleContainer.OpenStream(filename + ".wav");
SoundEffect effect = SoundEffect.FromStream(stream);
PlayAnimation message = new PlayAnimation(effect.Duration);
Messenger.Default.Send<PlayAnimation>(message);
FrameworkDispatcher.Update();
effect.Play();
}
This works great.
Now i want a small animation playing while the sound is playing. I'm thinking that i will just pass the length of the soundclip to the animation and then start it.
The messenger class sends a message (in the PlaySound method, above), and this code wires it up to a method
------ View / Xaml Constructor ------
Messenger.Default.Register<PlayAnimation>(this, ( action ) => PlayAnimation(action));
------ method PlayAnimation below ------
private void PlayAnimation(PlayAnimation parameter)
{
//Magic code starting the animation in the datatemplate of the listbox..
}
But i'm not exactly sure how i can start the animation.
The storyboard is a resource to the listbox, and the targetElement is the Arc element. So the animation is simply the arc element's startAngle, and is just there to illustrate that a sound i currently playing, and how long the sound duration is.
Somehow i need to get a hold of the storyboard, but since the targetElement is inside a data-template, how will i know how to play the correct animation. That is if i'm even able to get reference to the storyboard?
Thanks in advance! Please ask if there is anything
Upvotes: 0
Views: 778
Reputation: 984
First off define your animation in your data template.
Next instead of binding the CommandParameter to "FileName" bind it to the object in your data template where the animation is defined. Normally your data template will contain a root layout panel where the animation is defined as a resource. Make sure that has an x:Name and bind your CommandParameter to that. So if your root layout container were called "grid" bind the CommandParameter to it like this.
CommandParameter="{Binding ElementName=grid, Mode=OneWay}"
Now in the handler for your relay command change the parameter to reflect that you are now passing in a FrameworkElement rather than your file name string. Also change your code to extract the Storyboard and use the DataContext to get back to your viewmodel to get the filename of the sound.
private void PlaySound( FrameworkElement obj )
{
var animation = obj.Resources["MyAnimation"] as Storyboard;
animation.Begin();
var selected = obj.DataContext as SoundViewModel;
var filename = selected.FileName;
Stream stream = TitleContainer.OpenStream(filename + ".wav");
SoundEffect effect = SoundEffect.FromStream(stream);
PlayAnimation message = new PlayAnimation(effect.Duration);
Messenger.Default.Send<PlayAnimation>(message);
FrameworkDispatcher.Update();
effect.Play();
}
Upvotes: 1