Модераторы: gambit, Kefir, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> MVVM Управление MediaElement с ViewModel 
:(
    Опции темы
Rohoss
Дата 27.2.2011, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Сабж. Хочется управлять своим MediaElement расположенным в View с ViewModel. Хочется использовать такие методы как Play, Stop, Pause. Ищу правильное решения. В инете нашёл решения, в котором MediaElement держат непосредственно в ViewModel, но это как-то не по фен шую. 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
-Mikle-
Дата 27.2.2011, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 13
Всего: 59



Цитата(Rohoss @  27.2.2011,  18:27 Найти цитируемый пост)
В инете нашёл решения, в котором MediaElement держат непосредственно в ViewModel, но это как-то не по фен шую

Правильно, что вы говорите что это не правильно smile
Ну тут абстракция не должна быть более особенной, чем от, например, диалогового окна. Я для абстракции задач относящихся непосредственно к представлению использую интерфейсы, зарегестрированные в каком нить сервис-провайдере или контейнере, не важно. Также использую мессенджеры.
Ну а если требуется управлять вашим медиа только из одной модели представления, то вы можете обойтись делеагатами, передаваемыми из представления в модель, либо интерфесом каким-нить, который также передается в модель самим представлением, или событиями в модели на которые подвешивается представление, или биндинги в конце концов... Вариантов море, но однозначно, не следует размещать именно MediaElement на стороне модели представления. Другое дело, если механизм воспроизведения звука не будет UI-зависимым (DirectX например). Для такого, можно и модель отдельную сделать и уже к ней привязать представление. В общем смотрите как вам надо. По любому из перечисленных вариантов могу продолжить писать, если вам интересно.


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
Rohoss
Дата 27.2.2011, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Ну я создал на стороне представления свойство зависимости и через него уже управляю, но этот вариант тоже не особо хорош, потому что  code-behavior не пуст...


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
-Mikle-
Дата 28.2.2011, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 13
Всего: 59



А это смотря на сколько он не пуст. Если в его задачи входит только управление или малая часть связки на стороне только представления, без логики самого приложения, то это ничего страшного. Например, вы можете спокойно раместить обработчик клика кнопки (вместе или без заданной команды) если при клике меняется цвет фона например. Не состояние модели, от которого зависит цвет фона, а вот просто, чисто дизайнерский наворот. Либо вы можете спокойно размещать код, который мониторит или задает значения свойств модели лежащей в контексте данных (опять таки если это не связано с логикой приложения). Любо подцепиться на событие в модели. Общий смысл таков, что в код-бехинде не должен располагаться код, от которого зависит работа самого приложения. Не рекомендуется, например, связывание двух и более моделей в код-бехинде (да и через XAML тоже), так как что и с чем связано относится к логике. Идеально, когда одно представление знает только о той модели, для которого оно разработано. Это вполне достижимо (мне по крайней мере это удается). Я могу привести пример того, что вам необходимо, только скажите мне, какой способ абстракции из перечисленных мной в предыдущем посте вы предпочитаете.

Добавлено через 8 минут и 56 секунд
Код-бехинд, не обязан быть пустым. В шаблоне оговаривается, что он будет минимальным и в большинстве случаев вообще пустым, так как логика переносится в модель представления. Любая интерактивность с пользователем - это представление, а принятие решений по этому поводу - это модель рпедставления. Код-бехинд может содержать даже код связывания между элементами управления, если биндингом это недостижимо или биндинг получается нечитабельным.


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
Rohoss
Дата 3.3.2011, 01:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



-Mikle-, моё понимание паттерна mvvm было не совсем правильным, я почему то считал что view не должно иметь никакого кода, имеющего какого либо отношения к логике приложения, но похоже это совсем так... Оно и не должно его иметь (логику уровня приложения), однако оно должно иметь код, с помощью которого viewmodel может иметь контроль над view... Теперь я так понимаю данный паттерн... В принцепе то что вы описали в посте выше  smile 


Цитата(-Mikle- @  28.2.2011,  19:09 Найти цитируемый пост)
Я могу привести пример того, что вам необходимо, только скажите мне, какой способ абстракции из перечисленных мной в предыдущем посте вы предпочитаете.

Было бы очень хорошо если бы вы привили пример с использованием мессаджеров, так как о данных объектах я ничего не знаю


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
-Mikle-
Дата 6.3.2011, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 13
Всего: 59



Цитата(Rohoss @  3.3.2011,  04:24 Найти цитируемый пост)
не должно иметь никакого кода, имеющего какого либо отношения к логике приложения

К логике приложения да, не должно, а к логику привязки взаимодействия с моделью представления или логику самого представления внутри себя - пожалуйста.

Цитата(Rohoss @  3.3.2011,  04:24 Найти цитируемый пост)
 с использованием мессаджеров, так как о данных объектах я ничего не знаю 

Это не стандартные классы и поведение. В составе наших проектов мы используем самописный мессенджер. Он довольно тривиален и суть его такова, что любой объект в домене приложения может зарегистрироваться для получения сообщений определенного типа. Далее, любой объект может также отправлять сообщение какого-то типа и все зарегистрировавшиеся получатели его получают. Привести код этого класса я не могу, так как права на исходники принадлежат компании в которой я работаю, но я поискал щас в инете и нашел похожую реализацию этой идеи. Правда как я понял, та реализация куда более тривиальна, чем наша, но подойдет для простых задач.
Через мессенджер можно сделать так, чтобы view регистрировалась на получение сообщений своего типа. При получении сообщений, она выполняет соответствующие действия. Так как мессенджер является синглтон-объектом, то он доступен из любого места приложения и любая модель представления (не зависимо от того для чего она создана) в таком варианте может отправлять сообщения на воспроизведение звука или видео. Я приведу код мессенджера описывающий только идею без детальной реализации. Не берите за основу сигнатуры его методов, так как на самом деле нужно о многом позаботиться прежде, чем запоминать обработчик сообщения.

Код

public class SimplestExampleMessenger
{
    static SimplestExampleMessenger _instance = null;
    public static SimplestExampleMessenger Instance
    {
        get { return _instance ?? (_instance = new SimplestExampleMessenger()); }
    }

    public void Register<TMsgType>(Action<TMsgType> handler)
    {
        // запоминаем где-нибудь кто и какой метод 
        // хочет получать сообщения типа TMsgType
    }
    public void Send<TMsgType>(TMsgType message)
    {
        // у всех кто зарегился получение сообщения типа TMsgType
        // вызываем запомненный метод и передаем message в качестве параметра
    }
}


А вот примерная идея реализации на основе мессенджера:
1) Классы сообщений проигрывателя
Код

public abstract class MediaPlayerMessage
{
    public abstract string Action { get; }
    public bool Handled { get; set; }
    public int Key { get; set; }
}
public class PlayMediaMessage : MediaPlayerMessage
{
    public PlayMediaMessage(Stream source) { this.Source = source; }
    public Stream Source { get; private set; }
    public override string Action { get { return "play"; } }
}
public class StopMediaMessage : MediaPlayerMessage
{
    public StopMediaMessage(int key) { this.Key = key; }
    public override string Action { get { return "stop"; } }
}


2) Класс проигрывателя. Я сделал его пустым, так как ориентировался только на звук, который не имеет отображения. Нет никаких проблем сделать его таким, каким вы себе его представляете.
Код

<UserControl x:Class="SilverlightApplication2.MediaPlayer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Visibility="Collapsed">
</UserControl>

Код

using System;
using System.Collections.Generic;
using System.Windows.Controls;

namespace SilverlightApplication2
{
    public partial class MediaPlayer : UserControl
    {
        int lastKeyID = 0;
        Dictionary<int, MediaElement> currentMediaList = null;

        public MediaPlayer()
        {
            InitializeComponent();
            currentMediaList = new Dictionary<int, MediaElement>();
            SimplestExampleMessenger.Instance.Register<MediaPlayerMessage>(HandleMessage);
        }

        public void HandleMessage(MediaPlayerMessage message)
        {
            if (message is PlayMediaMessage)
            {
                MediaElement media = new MediaElement();
                message.Key = ++lastKeyID;
                currentMediaList.Add(message.Key, media);
                media.SetSource(((PlayMediaMessage)message).Source);
                media.MediaEnded += (s, e) => HandleMessage(new StopMediaMessage(message.Key));
                media.Play();
                message.Handled = true;
            }
            else if (message is StopMediaMessage)
            {
                MediaElement media = null;
                if (currentMediaList.TryGetValue(message.Key, out media))
                {
                    media.Stop();
                    currentMediaList.Remove(message.Key);
                }
                message.Handled = true;
            }
        }
    }
}


Теперь, если у вас в любом месте UI где-то расположен MediaPlayer (его не видно и он не будет мешать), то вы можете проигрывать сколько угодно мелодий одновременно.
Код

// воспроизвести
MediaPlayerMessage message = new PlayMediaMessage(new MemoryStream(Resource1.Amanda));
SimplestExampleMessenger.Instance.Send(message);
// message.Key теперь будет содержать идентификатор вашей мелодии
mediaKey = message.Key;

.....................

// остановить
SimplestExampleMessenger.Instance.Send(new StopMediaMessage(mediaKey));


Как видите, тут все очень просто. В этом примере даже близко нет ни упоминания ни использования MVVM. Всю задачу абстракции решает тут мессенджер. Код который отправляет сообщения, ничего не знает о проигрывателе. Проигрыватель вообще может не существовать и вызывающий код будет продолжать работать (просто беззвучно). А если отправляющей стороне необходимо знать проигрывается звук или нет, то я пердусмотрел в примере сообщения свойство Handled. MediaPlayer выставляет его в true, если она отработала сообщение. Также, вы можете в любой момент добавить новые поддерживаемые сообщения или заменить их обработчик например на DirectX. Абстрагировать через мессенджер можно даже несколько viewmodel между собой. В общем, думаю эта идея тут достаточно развернута, а мне пора идти гулять со своими детишками smile


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




[ Время генерации скрипта: 0.0481 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.