MVVM способ использовать разные элементы управления для редактирования разных объектов - PullRequest
0 голосов
/ 14 февраля 2011

Мне нужно спроектировать форму с видом на дерево слева и контейнером для какого-то другого элемента управления в оставшейся области. Всякий раз, когда пользователь выбирает элемент в древовидной структуре, справа появляется пользовательский элемент управления. Например, предположим, что древовидное представление содержит значения «Настройки звука» и «Настройки видео», и у меня есть два элемента управления, которые можно привязать к этим настройкам, и я хочу отображать их в форме при необходимости.

Теперь, из того, что я читал о MVVM, у меня не должно быть свойств, которые будут возвращать UserControls или DataTemplates, я прав? Это будет возиться с «VM не должен знать детали реализации представления», как я это вижу. Итак, как мне справиться с этой ситуацией правильно с точки зрения MVVM? Должен ли я использовать конвертеры для этого, и если да, то как бы это выглядело?

В настоящее время я не могу предоставить какой-либо код (в основном потому, что его нет), но я постараюсь прояснить проблему, если это необходимо. Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 14 февраля 2011

Здесь помогает система шаблонов WPF.

Основная идея состоит в том, чтобы ContentControl отображал соответствующий вид в зависимости от выбранного значения в TreeView.

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:l="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
    <DockPanel>

        <ListBox DockPanel.Dock="Left" ItemsSource="{Binding Editors}" SelectedItem="{Binding SelectedEditor}" />

        <ContentControl Content="{Binding SelectedEditor}">
            <ContentControl.Resources>
                <DataTemplate DataType="{x:Type l:VideoViewModel}">
                    <l:VideoView />
                </DataTemplate>
                <DataTemplate DataType="{x:Type l:AudioViewModel}">
                    <l:AudioView />
                </DataTemplate>
            </ContentControl.Resources>
        </ContentControl>

    </DockPanel>
</Window>

AudioView и VideoView равны UserControls.

Как видите, содержимое ContentControl привязано к свойству SelectedEditor в ViewModel, которое также привязано к SelectedItemListbox.

Таким образом, ViewModel для основного вида выглядит следующим образом.

public class MainWindowViewModel : INotifyPropertyChanged
{
    public IEnumerable<object> Editors
    {
        get
        {
            yield return new VideoViewModel();
            yield return new AudioViewModel();
        }
    }

    private object selectedEditor;
    public object SelectedEditor
    {
        get { return selectedEditor; }
        set
        {
            if (selectedEditor == value)
                return;
            selectedEditor = value;
            OnPropertyChanged("SelectedEditor");
        }
    }
}

Итак, вы можете видеть, что основной ViewModel не содержит данных GUI.

Чтобы обработать подключение TreeView к свойству SelectedItem в ViewModel, см. Привязка данных к SelectedItem в WPF Treeview

1 голос
/ 14 февраля 2011

Вы можете реализовать его, выбрасывая два свойства: ShowAudioSettings и ShowVideoSettings в ViewModel и привязывать его к видимости ваших элементов управления.

Кроме того, вы можете сделать это с помощью VisualStateManager .

...