Каков лучший способ в MVVM для создания меню, которое отображает различные страницы?

Для 64-битной Windows , убедитесь, что идея запускается в 64-битном режиме ( idea64.exe ) и измените настройки в «C: \ Program Files (x86) \ JetBrains». Файл \ IntelliJ IDEA 15.0.1 \ bin \ idea64.exe.vmoptions ". У меня эти настройки отлично работают

-Xms512m
-Xmx2024m
-XX:MaxPermSize=700m
-XX:ReservedCodeCacheSize=480m
8
задан Edward Tanguay 19 June 2009 в 15:07
поделиться

3 ответа

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

Теперь, если вы действительно хотите использовать чистый маршрут MVVM, все, что вам нужно сделать, чтобы заставить ваше меню запускать команду, сначала в некотором разделе ресурсов добавьте этот стиль:

<Style x:Key="MenuItemStyle" TargetType="MenuItem">
    <Setter Property="Command" 
            Value="{Binding DataContext.SwitchViewCommand,
            RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Menu}}}"/>
    <Setter Property="CommandParameter" 
            Value="{Binding}"/>
</Style>

Этот стиль сделает элемент меню запускает SwitchViewCommand в присоединенной модели представления с DataContext MenuItem в качестве параметра команды.

Фактическое представление такое же, как и ваш код, с дополнительной ссылкой на этот стиль в виде ItemContainerStyle (поэтому оно применяется к элементу меню, а не к содержимому DataTemplate):

<DockPanel LastChildFill="False">

    <Menu DockPanel.Dock="Top"
        ItemsSource="{Binding PageItemsMainMenu}" 
        ItemTemplate="{StaticResource MainMenuStyle}"
        ItemContainerStyle="{StaticResource MenuItemStyle}"/>
    <ContentControl 
    Content="{Binding SelectedPageItem}"/>
</DockPanel>

Теперь в модели представления, которая вам нужна ( Я использовал строки, потому что у меня нет вашего кода PageItem):

private string _selectedViewItem;
public List<string> PageItemsMainMenu { get; set; }
public string SelectedPageItem
{
    get { return _selectedViewItem; }
    set { _selectedViewItem = value; OnNotifyPropertyChanged("SelectedPageItem"); }
}
public ICommand SwitchViewCommand { get; set; }

И используйте любой класс команд, который вы используете, чтобы команда вызывала этот код:

private void DoSwitchViewCommand(object parameter)
{
    SelectedPageItem = (string)parameter;
}

Теперь, когда пользователь щелкает элемент меню, элемент меню вызывает SwitchViewCommand с элементом страницы в качестве параметра.

Команда вызовет DoSwitchViewCommand, который установит свойство SelectedPageItem

Свойство вызовет NotifyPropertyChanged, что приведет к обновлению пользовательского интерфейса через привязку данных.

Или вы можете напишите двухстрочный обработчик событий на ваш выбор

<DockPanel LastChildFill="False">

    <Menu DockPanel.Dock="Top"
        ItemsSource="{Binding PageItemsMainMenu}" 
        ItemTemplate="{StaticResource MainMenuStyle}"
        ItemContainerStyle="{StaticResource MenuItemStyle}"/>
    <ContentControl 
    Content="{Binding SelectedPageItem}"/>
</DockPanel>

Теперь в модели представления, которая вам нужна (я использовал строки, потому что у меня нет вашего кода PageItem):

private string _selectedViewItem;
public List<string> PageItemsMainMenu { get; set; }
public string SelectedPageItem
{
    get { return _selectedViewItem; }
    set { _selectedViewItem = value; OnNotifyPropertyChanged("SelectedPageItem"); }
}
public ICommand SwitchViewCommand { get; set; }

И используйте любой класс команд, который вы используете, чтобы команда вызывала этот код:

private void DoSwitchViewCommand(object parameter)
{
    SelectedPageItem = (string)parameter;
}

Теперь, когда пользователь щелкает элемент меню, элемент меню вызывает SwitchViewCommand с элементом страницы в качестве параметра.

Команда вызывает DoSwitchViewCommand, который устанавливает свойство SelectedPageItem.

Свойство вызывает NotifyPropertyChanged, что приводит к обновлению пользовательского интерфейса через привязку данных.

Или вы можете написать двухстрочный обработчик событий на ваш выбор

<DockPanel LastChildFill="False">

    <Menu DockPanel.Dock="Top"
        ItemsSource="{Binding PageItemsMainMenu}" 
        ItemTemplate="{StaticResource MainMenuStyle}"
        ItemContainerStyle="{StaticResource MenuItemStyle}"/>
    <ContentControl 
    Content="{Binding SelectedPageItem}"/>
</DockPanel>

Теперь в модели представления, которая вам нужна (я использовал строки, потому что у меня нет вашего кода PageItem):

private string _selectedViewItem;
public List<string> PageItemsMainMenu { get; set; }
public string SelectedPageItem
{
    get { return _selectedViewItem; }
    set { _selectedViewItem = value; OnNotifyPropertyChanged("SelectedPageItem"); }
}
public ICommand SwitchViewCommand { get; set; }

И используйте любой класс команд, который вы используете, чтобы команда вызывала этот код:

private void DoSwitchViewCommand(object parameter)
{
    SelectedPageItem = (string)parameter;
}

Теперь, когда пользователь щелкает элемент меню, элемент меню вызывает SwitchViewCommand с элементом страницы в качестве параметра.

Команда вызывает DoSwitchViewCommand, который устанавливает свойство SelectedPageItem.

Свойство вызывает NotifyPropertyChanged, что приводит к обновлению пользовательского интерфейса через привязку данных.

Или вы можете написать двухстрочный обработчик событий на ваш выбор

Команда вызовет DoSwitchViewCommand, который установит свойство SelectedPageItem.

Свойство вызовет NotifyPropertyChanged, что приведет к обновлению пользовательского интерфейса через привязку данных.

Или вы можете написать двухстрочный обработчик событий по вашему выбору

Команда вызовет DoSwitchViewCommand, который установит свойство SelectedPageItem.

Свойство вызовет NotifyPropertyChanged, что приведет к обновлению пользовательского интерфейса через привязку данных.

Или вы можете написать двухстрочный обработчик событий по вашему выбору

9
ответ дан 5 December 2019 в 19:02
поделиться

Другой вариант - использовать ListBox вместо меню, оформить ListBox так, чтобы он выглядел как меню, а затем вы можете привязать к выбранному значению, например:

<DockPanel LastChildFill="False">

    <ListBox 
        ItemsSource="{Binding PageItemsMainMenu}" 
        ItemTemplate="{StaticResource MainMenuStyle}"
        IsSynchronizedWithCurrentItem="True"/>

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

</DockPanel>

Обратите внимание на IsSynchronizedWithCurrentItem = «True», чтобы установить выбранный элемент и {Binding PageItemsMainMenu /} с косой чертой в конце, чтобы использовать его.

0
ответ дан 5 December 2019 в 19:02
поделиться

Я мог бы представить ObservableCollection в виртуальной машине, которая содержит все страницы, вызываемые из меню. Затем привяжите к нему ItemsControl и ContentControl, чтобы ContentControl всегда отображал CurrentItem из этого списка. Конечно, меню будет привязано только к некоторому свойству Title. тогда как ContentControl примет весь элемент и подключит некоторое подходящее представление в соответствии с типом.

0
ответ дан 5 December 2019 в 19:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: