MVVM способ представления элементов управления динамически - PullRequest
1 голос
/ 09 сентября 2011

Мне нужно отобразить какую-то анимацию, когда запускаются разные процессы.Моя первоначальная идея состояла в том, чтобы просто добавить некоторые теги <ContentControl> в XAML и связать их со свойством в объекте модели представления, которое затем просто присвоило этому свойству ProgressBar, некоторый занятый счетчик или что-то еще.

Это работает, но мне это не нравится.Основная причина, по которой мне это не нравится, заключается в том, что модель представления не должна вовлекать себя в вопросы представления, и этот шаблон явно нарушает эту парадигму.

Это в значительной степени то, как мой (уродливый) код выглядит как atm:

XAML:

<ContentControl Content="{Binding ProcessAAnimation}" />

В классе View Model:

public object ProcessAAnimation 
{ 
    get { return _processAAnimation; }
    private set
    { 
        _processAAnimation = value;
        OnPropertyChanged("ProcessAAnimation");
    }
}

public object IsProcessARunning
{
    get { return _processARunning; }
    private set 
    {
        if (value == _processARunning)
            return;
        _processRunnings = value;
        if (value)
            ProcessAAnimation = SomeNiftyAnimationControl();
        else
        {
            if (ProcessAAnimation is IDisposable)
                ((IDisposable)ProcessAAnimation).Dispose();
            ProcessAAnimation = null;
        }
    }
}

// (clipped: More properties for "Process B", "Process C" and so on)

Итак, есть лучший шаблон для достижения этой цели.Предпочтительно шаблон, в котором я могу динамически создавать свои элементы управления анимацией, используя только XAML?

Обратите внимание, что я уже протестировал решение, в котором я объявляю три различных элемента управления анимацией, а затем связываю их свойство Visibility с моделью представления.государство.Это, однако, ниже номинала в моей книге, потому что я не хочу просто скрывать элементы управления, я хочу, чтобы они исчезли без необходимости.Кроме того, это также сделало бы невозможным динамическое использование различных типов анимации для любых потребностей.

Кто-нибудь?

1 Ответ

2 голосов
/ 09 сентября 2011

Ну, ваша ViewModel знает об операции и о самом прогрессе. Остальное можно выполнить с помощью триггеров. По крайней мере, так мы это делаем. Таким образом, ваш ViewModel имеет, например, свойство «IsLoadingImage», которое устанавливается, когда ваша viewmodel запускает BackgroundWorker для загрузки большого изображения, она также возвращает прогресс, сообщенный BackgroundWorker «ImageLoadingProgress», теперь этих двух свойств достаточно для передачи вашему представлению. , Ваше представление состоит из индикатора выполнения или пользовательского элемента управления для вашей специальной анимации. Теперь вы можете привязать «IsLoadingImage» в триггере, чтобы переключать видимость элемента управления ProgressBar / Animation, и значение их привязано к «ImageLoadingProgress».

Как я уже сказал, именно так мы и поступаем, и наше приложение интенсивно использует MVVM.

Редактировать ответ на комментарий: Как изменить шаблон в триггере

<ControlTemplate x:Name="ActiveTemplate" TargetType="{x:Type MyType}">
  <!-- Template when active -->
</ControlTemplate>

<ControlTemplate x:Name="DeactivatedTemplate" TargetType="{x:Type MyType}">
  <!-- Template when deactivated -->
</ControlTemplate>

<Style TargetType="{x:Type MyType}">
    <Setter Property="Template" Value="{StaticResource DeactivatedTemplate}"/>

    <Style.Triggers>
        <DataTrigger Binding="{Binding IsActive}" Value="True">
            <Setter Property="Template" Value="{StaticResource ActiveTemplate}"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

Предполагается, что MyType является элементом управления, который может иметь ControlTemplate, и что DataContext имеет свойство IsActive для переключения шаблона.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...