为什么C#WPF按钮绑定命令获胜';使用简单喷油器后是否改变视图?

为什么C#WPF按钮绑定命令获胜';使用简单喷油器后是否改变视图?,c#,wpf,xaml,mvvm,simple-injector,C#,Wpf,Xaml,Mvvm,Simple Injector,我将以下文章用于初学者代码: 目标: 尝试使用按钮绑定命令和简单的注入器在WPF表单中从视图1转到视图2,以向视图中注入依赖项。注意:这些依赖关系是保存来自外部源的数据的存储库 问题: 使用Simple Injector将依赖项注入到我的MainWindow和MainWindowViewModel后,我的按钮不再更改我的当前视图(到我的另一个视图)。当使用Visual Studio并使用断点进行调试时,代码似乎永远卡在RelayCommand.cs(请参阅)的CanExecute函数中的循环

我将以下文章用于初学者代码:

目标:
尝试使用按钮绑定命令和简单的注入器在WPF表单中从视图1转到视图2,以向视图中注入依赖项。注意:这些依赖关系是保存来自外部源的数据的存储库

问题:
使用Simple Injector将依赖项注入到我的MainWindow和MainWindowViewModel后,我的按钮不再更改我的当前视图(到我的另一个视图)。当使用Visual Studio并使用断点进行调试时,代码似乎永远卡在RelayCommand.cs(请参阅)的
CanExecute
函数中的循环中,在该函数中有东西在反复调用它。我无法对
CanExecute
函数进行更多调试,因为有很多代码被传递(来自DLL等)。当不使用断点时,我的按钮似乎什么都不做

在输出窗口中没有按钮错误,也没有抛出异常。命令绑定正在工作,因为我可以看到调试时调用MainWindowViewModel.cs中的函数
OnGo2Screen
。调用
OnGo2Screen
后,它会按预期在代码中移动,直到卡在
CanExecute

我尝试过的
我已经检查了主窗口的数据上下文,可以看出它具有所有正确的功能

我为这篇文章做了一个单独的项目,我能够很好地改变视图。但每当我尝试使用简单的注射器时,我的按钮就断了

我注意到,当不使用Simple Injector时,代码从
CanExecute
函数移动到
CanExecuteChanged
EventHandler,并执行移除和添加变体,然后按预期更改视图。但是,当使用简单喷油器时,它不会这样做

代码
我正在使用我的App.xaml.cs作为启动程序,其中我的App.xaml的构建操作为“Page”

SimulationCaseView是视图1(默认的起始视图)。
StreamsView是视图2(只是另一个视图)。
UserControl3是视图3(只是另一个视图)

下面是我的代码。请参考为任何剩余代码提供的两个链接,因为我基于这两个链接编写了许多函数

App.xaml


App.xaml.cs

名称空间MyApp.Desktop
{
/// 
///App.xaml的交互逻辑
/// 
公共部分类应用程序:应用程序
{
App()
{
初始化组件();
}
[状态线程]
静态void Main()
{
var container=Bootstrap();
//任何其他配置,例如所需的MVVM工具包。
运行应用程序(容器);
}
私有静态容器引导()
{
//像往常一样创建容器。
var container=新容器();
//注册您的类型,例如:
容器。登记(生活方式。单身);
容器。登记(生活方式。单身);
//注册您的windows和视图模型:
container.Register();
container.Register();
container.Verify();
返回容器;
}
专用静态void运行应用程序(容器)
{
尝试
{
var app=新app();
var mainWindow=container.GetInstance();
MainWindowViewModel viewModel=container.GetInstance();
mainWindow.DataContext=viewModel;
应用程序运行(主窗口);
}
捕获(例外情况除外)
{
控制台写入线(ex);
}
}
}
}
MainWindow.xaml


MainWindowViewModel.cs

名称空间MyApp.Desktop.Views
{
公共类MainWindowViewModel:BaseViewModel
{
私有IPageViewModel\u currentPageViewModel;
私有列表pageViewModels;
公共列表页面视图模型
{
得到
{
如果(_pageViewModels==null)
_pageViewModels=新列表();
返回页面视图模型;
}
}
公共IPageViewModel CurrentPageViewModel
{
得到
{
返回_currentPageViewModel;
}
设置
{
_currentPageViewModel=值;
OnPropertyChanged(“CurrentPageViewModel”);
}
}
私有void ChangeViewModel(IPageViewModel viewModel)
{
如果(!PageViewModels.Contains(viewModel))
PageViewModels.Add(viewModel);
CurrentPageViewModel=PageViewModels
.FirstOrDefault(vm=>vm==viewModel);
}
专用void ONGO1屏幕(对象obj)
{
ChangeViewModel(PageViewModels[0]);
}
私有void ONGO2屏幕(对象obj)
{
ChangeViewModel(PageViewModels[1]);
}
私有void ONGO3屏幕(对象obj)
{
ChangeViewModel(PageViewModels[2]);
}
公共主窗口视图模型(IStreamRepository streamRepository)
{
//添加可用页面并设置页面
添加(新的SimulationCaseViewModel(streamRepository));
添加(新的StreamsViewModel());
添加(新的UserControl3ViewModel());
CurrentPageViewModel=PageViewModels[0];
调解人。订阅(“GoTo1Screen”,OnGo1Screen);
调解人。订阅(“GoTo2Screen”,OnGo2Screen);
调解员
<Application x:Class="MyApp.Desktop.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:views="clr-namespace:MyApp.Desktop.Views">
    <Application.Resources>
        <DataTemplate DataType="{x:Type views:SimulationCaseViewModel}">
            <views:SimulationCaseView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type views:StreamsViewModel}">
            <views:StreamsView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type views:UserControl3ViewModel}">
            <views:UserControl3 />
        </DataTemplate>
    </Application.Resources>
</Application>
namespace MyApp.Desktop
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        App()
        {
            InitializeComponent();
        }

        [STAThread]
        static void Main()
        {
            var container = Bootstrap();

            // Any additional other configuration, e.g. of your desired MVVM toolkit.

            RunApplication(container);
        }


        private static Container Bootstrap()
        {
            // Create the container as usual.
            var container = new Container();

            // Register your types, for instance:
            container.Register<IPreferencesRepository, PreferencesRepository>(Lifestyle.Singleton);
            container.Register<IStreamRepository, StreamRepository>(Lifestyle.Singleton);

            // Register your windows and view models:
            container.Register<MainWindow>();
            container.Register<MainWindowViewModel>();

            container.Verify();

            return container;
        }

        private static void RunApplication(Container container)
        {
            try
            {
                var app = new App();
                var mainWindow = container.GetInstance<MainWindow>();
                MainWindowViewModel viewModel = container.GetInstance<MainWindowViewModel>();
                mainWindow.DataContext = viewModel;
                app.Run(mainWindow);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
    }
}
<Window x:Class="MyApp.Desktop.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyApp.Desktop"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="350" Width="525"
        xmlns:views="clr-namespace:MyApp.Desktop.Views">
    <Grid>
        <ContentControl Content="{Binding CurrentPageViewModel}" />
    </Grid>
</Window>
namespace MyApp.Desktop.Views
{
    public class MainWindowViewModel : BaseViewModel
    {
        private IPageViewModel _currentPageViewModel;
        private List<IPageViewModel> _pageViewModels;

        public List<IPageViewModel> PageViewModels
        {
            get
            {
                if (_pageViewModels == null)
                    _pageViewModels = new List<IPageViewModel>();

                return _pageViewModels;
            }
        }

        public IPageViewModel CurrentPageViewModel
        {
            get
            {
                return _currentPageViewModel;
            }
            set
            {
                _currentPageViewModel = value;
                OnPropertyChanged("CurrentPageViewModel");
            }
        }

        private void ChangeViewModel(IPageViewModel viewModel)
        {
            if (!PageViewModels.Contains(viewModel))
                PageViewModels.Add(viewModel);

            CurrentPageViewModel = PageViewModels
                .FirstOrDefault(vm => vm == viewModel);
        }

        private void OnGo1Screen(object obj)
        {
            ChangeViewModel(PageViewModels[0]);
        }

        private void OnGo2Screen(object obj)
        {
            ChangeViewModel(PageViewModels[1]);
        }
        private void OnGo3Screen(object obj)
        {
            ChangeViewModel(PageViewModels[2]);
        }

        public MainWindowViewModel(IStreamRepository streamRepository)
        {
            // Add available pages and set page
            PageViewModels.Add(new SimulationCaseViewModel(streamRepository));
            PageViewModels.Add(new StreamsViewModel());
            PageViewModels.Add(new UserControl3ViewModel());

            CurrentPageViewModel = PageViewModels[0];

            Mediator.Subscribe("GoTo1Screen", OnGo1Screen);
            Mediator.Subscribe("GoTo2Screen", OnGo2Screen);
            Mediator.Subscribe("GoTo3Screen", OnGo3Screen);
        }
    }
}
<UserControl x:Class="MyApp.Desktop.Views.SimulationCaseView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:MyApp.Desktop"
             mc:Ignorable="d"
             d:DesignHeight="280" d:DesignWidth="280">
    <Grid>
        <Button
            Content="Go to Streams"
            Command="{Binding GoTo2}"
            Width="90" Height="30" Margin="166,220,24,30">
        </Button>
    </Grid>
</UserControl>
namespace MyApp.Desktop.Views
{
    public class SimulationCaseViewModel : BaseViewModel, IPageViewModel
    {
        private ICommand _goTo2;
        private readonly IStreamRepository _repo;
        public SimulationCaseViewModel(IStreamRepository repo)
        {
            _repo = repo;
            Application application = _repo.GetApplicationReference();
            CurrentSimulationCases = new ObservableCollection<SimulationCase>();
            Streams = new ObservableCollection<object>();
            foreach (SimulationCase simulationCase in application.SimulationCases)
            {
                CurrentSimulationCases.Add(simulationCase);
            }
            //FetchStreams = new RelayCommand(OnFetch);
        }

        public ObservableCollection<SimulationCase> CurrentSimulationCases { get; set; }
        public ObservableCollection<object> Streams { get; private set; }

        public ICommand GoTo2
        {
            get
            {
                return _goTo2 ?? (_goTo2 = new RelayCommand(x =>
                {
                    Mediator.Notify("GoTo2Screen", "");
                }));
            }
        }
    }
}
CommandManager.InvalidateRequerySuggested();
    private static Container Bootstrap()
    {
        // Create the container as usual.
        var container = new Container();

        // Register your types, for instance:


        // Register your windows and view models:
        //container.Register<MainWindow>(Lifestyle.Singleton); //not needed
        container.Register<MainWindowViewModel>(Lifestyle.Singleton);

        container.Verify();

        return container;
    }
    private static void RunApplication(Container container)
    {
        try
        {
            var mainWindow = container.GetInstance<MainWindow>();
            var app = new App();
            app.InitializeComponent();
            app.Run(mainWindow);
        }
        catch (Exception ex)
        {
            //Log the exception and exit
            Debug.WriteLine(ex.Message);
        }
    }
        //container.Register<MainWindow>(); // => Lifestyle.Transient;
        container.Register<MainWindowViewModel>(); // => Lifestyle.Transient;

        //container.Verify();
    public static void Subscribe(string token, Action<object> callback)
    {
        if (!pl_dict.ContainsKey(token))
        {
            var list = new List<Action<object>>();
            list.Add(callback);
            pl_dict.Add(token, list);
        }
        else
        {
            bool found = false;
            //foreach (var item in pl_dict[token])
            //    if (item.Method.ToString() == callback.Method.ToString())
            //        found = true;
            if (!found)
                pl_dict[token].Add(callback);
        }
    }
public interface IComponent
{
     void OnGo1Screen(object obj);
     void OnGo2Screen(object obj);
}
public class MainWindowViewModel : BaseViewModel, IComponent
  public MainWindowViewModel()
  {
     // Add available pages and set page
     PageViewModels.Add(new UserControl1ViewModel());
     PageViewModels.Add(new UserControl2ViewModel());

     CurrentPageViewModel = PageViewModels[0];

     //Mediator.Subscribe("GoTo1Screen", OnGo1Screen);
     //Mediator.Subscribe("GoTo2Screen", OnGo2Screen);
  }
            var context = mainWindow.DataContext as IComponent;
            Mediator.Subscribe("GoTo1Screen", context.OnGo1Screen);
            Mediator.Subscribe("GoTo2Screen", context.OnGo2Screen);