Запустить анимацию внутри таблицы данных списка из модели представления с помощью MVVMLight - PullRequest
0 голосов
/ 18 июля 2011

Для изучения WP7 я создаю простое приложение на звуковой панели.

Это мой код.Пожалуйста, спросите, не случайно ли я что-то упустил в своих попытках упростить вещи.

MainViewModel содержит эту коллекцию

public ObservableCollection<SoundViewModel> Sounds { get; private set; }

soundViewModel содержит эти свойства, они оба уведомляют о любых изменениях свойств

public string FileName
public string Name

Xaml / View содержит список, привязанный к коллекции Sounds на 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>

Когда я нажимаю кнопку, параметр / имя файла используется, чтобы найти файл и вызвать следующееmethod.

Этот метод заключен в RelayCommand и привязан к кнопке на табличке данных

    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();
    }

Это прекрасно работает.

Теперь я хочу, чтобы небольшая анимация воспроизводилась, покаЗвук играет.Я думаю, что я просто передам длину звукового клипа анимации, а затем запустю его.

Класс messenger отправляет сообщение (в методе PlaySound выше), и этот код связывает его сметод

    ------ 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..
    }

Но я не совсем уверен, как запустить анимацию.

Раскадровка - это ресурс для списка, а targetElement - это элемент Arc.Так что анимация - это просто startAngle элемента arc, и она служит для иллюстрации того, какой звук я сейчас играю, и какова длительность звука.

Каким-то образом мне нужно ухватиться за раскадровку, но так какtargetElement находится внутри шаблона данных, как я узнаю, как правильно воспроизводить анимацию.То есть если я даже смогу получить ссылку на раскадровку?

Заранее спасибо!Пожалуйста, спросите, если есть что-нибудь

1 Ответ

1 голос
/ 18 июля 2011

Сначала определите вашу анимацию в шаблоне данных.

Далее вместо привязки CommandParameter к «FileName» свяжите его с объектом в шаблоне данных, где определена анимация. Обычно ваш шаблон данных будет содержать корневую панель макета, где анимация определяется как ресурс. Убедитесь, что у него есть x: Name, и привяжите к нему свой CommandParameter. Поэтому, если ваш корневой макет контейнера назывался «grid», привяжите к нему CommandParameter следующим образом.

CommandParameter="{Binding ElementName=grid, Mode=OneWay}" 

Теперь в обработчике вашей команды реле измените параметр, чтобы отразить, что вы сейчас передаете FrameworkElement, а не строку имени файла. Также измените код, чтобы извлечь раскадровку, и используйте DataContext, чтобы вернуться к своей модели представления, чтобы получить имя файла звука.

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();
}
...