gpt4 book ai didi

c# - Caliburn.Micro GetAllInstances 只返回一个 viewModel(Caliburn.Micro MVVM)

转载 作者:行者123 更新时间:2023-12-03 10:33:27 29 4
gpt4 key购买 nike

我一直在尝试将 Caliburn.Micro MVVM 框架集成到我处于中间位置的 C# WPF 项目中。

我目前只有三个 View 模型:

  • ShellViewModel -(带有 ContentControl 的窗口 View )
  • AboutViewModel -(用户控件 View )
  • ChatViewModel -(另一个用户控件 View )

  • 目前,我正在尝试在 AboutView 上使用一个按钮,该按钮绑定(bind)到 AboutViewModel 上的“Chat()”方法,应该将用户带到 ChatView,但我正在使用 AboutViewModel 进行测试。 (如处理程序中所见)

    我需要的是所有 Screen/ViewModels 都是 Singleton 并且只有一个实例,当我尝试更改页面时,它会返回到已经存在的页面。

    这里的问题是,当我执行 IoC.GetAllInstances()、ShellViewModel 时,我只注册了一个实例,即使我在 Bootstrap 中尝试了多种配置,我也无法注册其他 ViewModel 以使其实例“可访问” "

    感谢您抽出宝贵时间,这是我认为与该问题相关的代码:

    这是我的 Bootstrap :
    public class AppBootstrapper : BootstrapperBase
    {
    private SimpleContainer _container = new SimpleContainer();

    public AppBootstrapper()
    {
    Initialize();

    var config = new TypeMappingConfiguration
    {
    DefaultSubNamespaceForViewModels = "ViewModel",
    DefaultSubNamespaceForViews = "View"
    };

    ViewLocator.ConfigureTypeMappings(config);
    Caliburn.Micro.ViewModelLocator.ConfigureTypeMappings(config);
    }

    protected override void Configure()
    {
    _container.Singleton<ShellViewModel, ShellViewModel>();
    _container.Singleton<IWindowManager, WindowManager>();
    //tried registering AboutViewModel in multiple ways
    _container.Singleton<AboutViewModel, AboutViewModel>();
    _container.RegisterSingleton(typeof(AboutViewModel), null,typeof(AboutViewModel));

    /
    }

    protected override void OnStartup(object sender, StartupEventArgs e)
    {
    DisplayRootViewFor<ShellViewModel>();
    }


    protected override object GetInstance(Type service, string key)
    {
    var instance = _container.GetInstance(service, key);
    if (instance != null)
    return instance;
    throw new InvalidOperationException("Could not locate any instances.");
    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
    return _container.GetAllInstances(service);
    }

    protected override void BuildUp(object instance)
    {
    _container.BuildUp(instance);
    }


    }

    ShellViewModel.cs:
    public class ShellViewModel : Conductor<object>, IHandle<NavigationMessage>
    {
    /// <summary>
    /// Caliburn.Micro event aggregator. (Publish/Subscribe pattern)
    /// </summary>
    public IEventAggregator events = new EventAggregator();
    public ShellViewModel()
    {
    //var aaa = IoC.Get<IEventAggregator>();
    events.Subscribe(this);
    ActivateItem(new AboutViewModel(events));
    }

    public void Handle(NavigationMessage message)
    {
    //var instance = IoC.GetInstance(message.ViewModelType,null);
    var instances = IoC.GetAllInstances(null);
    foreach(var i in instances)
    {

    MessageBox.Show(i.ToString());
    }
    ActivateItem(new AboutViewModel(events));

    }
    }

    还有 AboutViewModel.cs:
    /// <summary>
    /// ViewModel belonging to the AboutView.xaml.
    /// </summary>
    /// <seealso cref="AboutView.xaml"/>
    public class AboutViewModel : Screen, IHandle<NavigationMessage>
    {
    private readonly IEventAggregator _eventAggregator;
    /// <summary>
    /// Private container for the 'Version' public property.
    /// </summary>
    /// <see cref="Version"/>
    private string _version;

    /// <summary>
    /// Property containing a string of the application's current version (e.g.: 0.1.3.45)
    /// </summary>
    /// <see cref="_version"/>
    [JsonIgnore]
    public string Version
    {
    get
    {
    return _version;
    }
    set
    {
    _version = value;
    NotifyOfPropertyChange(() => Version);
    }
    }

    /// <summary>
    /// Base constructor for the AboutViewModel class.
    /// </summary>
    public AboutViewModel(IEventAggregator eventAggregator)
    {
    Logging.Info("Initialize AboutViewModel", this.GetType());
    Logging.Debug("Subscribing to the eventAggregator", this.GetType());
    _eventAggregator = eventAggregator;
    _eventAggregator.Subscribe(this);

    _version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
    Logging.Debug("Version loaded (" + _version + ")", this.GetType());
    }

    /// <summary>
    /// Boolean method connected to the ChatCommand activates or deactivates based on it's return
    /// </summary>
    /// <param name="obj">Object of type GotoPageMessage received from the messenger</param>
    public bool CanChat(object obj)
    {
    return true;
    }
    /// <summary>
    /// Method connected to the ChatCommand that sends the user to the 'Chat' view
    /// </summary>
    /// <param name="obj">Object of type GotoPageMessage received from the messenger</param>
    public void Chat(object obj)
    {

    _eventAggregator.PublishOnUIThread(new NavigationMessage(typeof(AboutViewModel)));
    }

    public void Handle(NavigationMessage message)
    {
    //This handle is used only to know how many instances I have active
    MessageBox.Show("about");
    }
    }

    编辑 1:

    P.S.:我曾经将 ShellViewModel 设置为 Conductor.Collection.OneActive。仍然没有工作。也许 AllActive 可能会起作用?...

    最佳答案

    覆盖 caliburn micro 的 SelectAssemblies 方法以定位所有 View :

    protected override IEnumerable<Assembly> SelectAssemblies()
    {
    return new[]
    {
    Assembly.GetExecutingAssembly(), typeof(MainViewModel).Assembly
    };
    }

    更多关于 Bootstrap here .

    关于c# - Caliburn.Micro GetAllInstances 只返回一个 viewModel(Caliburn.Micro MVVM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44890160/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com