处理WPF用户控件,视图模型和命令的正确方法

问题描述 投票:0回答:1

在WPF中有些怪异的论述之后,我认为我的方法正确。

我的目标是一个带有菜单和两个(或更多)用户控件的MainWindow,在鼠标单击时显示。每个用户控件都有自己的视图模型。因此,在这里提出了一些(愚蠢的?)问题之后,我解决了创建全局视图模型(ViewModelLocator)实例的问题,该实例继承了usercontrols的视图模型。我将此ViewModelLocator绑定到MainWindow的Datacontext,将ViewModels绑定到每个控件的Datacontext。现在,我的下一步是显示用户控件,该命令已触发。当然,如果尚未显示它,则必须显示它,因此,如果在MainWindow的ContentControl中显示了控件,则需要进行类似检查的操作。 (实际上,我在后台代码中执行此操作)

首先,一些代码... MainWindow.xaml

<ribbon:RibbonWindow
x:Class="PlcGenerator.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ribbon="clr-namespace:System.Windows.Controls.Ribbon;assembly=System.Windows.Controls.Ribbon"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:PlcGenerator"
    xmlns:viewmodels="clr-namespace:PlcGenerator.ViewModels"
    xmlns:views="clr-namespace:PlcGenerator.Views"
    mc:Ignorable="d"
    Loaded="Window_Loaded"
    Closing="ClosingApp"
    DataContext="{Binding ViewModelLocator, Source={StaticResource Locator}}"
    Title="Plc Generator" Height="600" Width="1200">

<Window.Resources>
    <DataTemplate x:Name="settingsViewTemplate" DataType="{x:Type viewmodels:SettingsViewModel}">
        <views:SettingsView DataContext="{Binding SettingsVM, Source={StaticResource Locator}}"/>
    </DataTemplate>
    <DataTemplate x:Name="projectsViewTemplate" DataType="{x:Type viewmodels:ProjectViewModel}">
        <views:ProjectView DataContext="{Binding ProjectVM, Source={StaticResource Locator}}"/>
    </DataTemplate>
</Window.Resources>

<DockPanel LastChildFill="True">

    <ribbon:Ribbon DockPanel.Dock="Top">
        <Ribbon.ApplicationMenu>
            <RibbonApplicationMenu SmallImageSource="Icons/ApplicationMenu.png">
                <RibbonApplicationMenuItem Header="Show Project View" Command="{Binding ProjectVM.ShowViewCommand}/>
                <RibbonApplicationMenuItem Header="Show Settings View" Command="{Binding SettingsVM.ShowViewCommand}/>
            </RibbonApplicationMenu>
        </Ribbon.ApplicationMenu>
    </ribbon:Ribbon>

        <!-- Fensterinhalt-->
    <ContentControl Margin="5" Content="{Binding}"/>

</DockPanel>

App.xaml:

<Application x:Class="PlcGenerator.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:PlcGenerator"
         StartupUri="MainWindow.xaml">
    <Application.Resources>
        <local:ViewModelLocator x:Key="Locator" />
    </Application.Resources>
</Application>

ViewModelLocator:

using PlcGenerator.ViewModels;

namespace PlcGenerator
{
    public class ViewModelLocator
    {
        public ViewModelLocator()
        {
            this.ProjectVM = new ProjectViewModel();
            this.SettingsVM = new SettingsViewModel();
        }
        public ProjectViewModel ProjectVM{ get; set; }
        public SettingsViewModel SettingsVM { get; set; }
    }
}

其中一个视图模型:

using System.Windows;
using System.Windows.Input;

namespace PlcGenerator.ViewModels
{
  public class ProjectViewModel
  {
    public ICommand ShowViewCommand { get; set; }

    public ProjectViewModel()
    {
        ShowViewCommand = new Commands.Command(ExecuteMehtod, canExecuteMethod);
    }

    private bool canExecuteMethod(object parameter)
    {
        return true;
    }
    private void ExecuteMehtod(object parameter)
    {
        //HWO CAN I SHOW THE VEIW HERE, AFTER TESTING IF IT'S ALREADY SHOWN?
        MessageBox.Show("Command fired");
    }

    //public string ProjectName { get; set; }
    public string ProjectName {
        get { return "MyProject"; //only for tests }
        set { }
    }

    public string ProjectFile { get; set; }

    public string ProjectFolder
    {
        get
        {
            int index = ProjectFile.LastIndexOf(".");
            if (index != -1)
                return this.ProjectFile.Substring(0, index);
            return string.Empty;
        }
    }
  }
}

简单的问题,如何检查UserControl是否已经加载到ContentControl中,如果没有,如何在其中显示它?

感谢@Eva和@ mm8到目前为止的帮助。

Carsten

c# wpf xaml mvvm command
1个回答
0
投票

我真的建议您看一下caliburn micro,它可以为您做得更好:https://caliburnmicro.com/

© www.soinside.com 2019 - 2024. All rights reserved.