【发布时间】:2020-05-25 16:56:34
【问题描述】:
我确信这个问题之前应该被问过,但我无法找到我正在寻找的确切内容;
考虑以下几点:
- Solution
-- Class Library Project [Caliburn.Micro] Referenced
--- [Models] Folder
---- LogEntryModel.cs
--- [ViewModels] Folder
---- LogEntryViewModel.cs
---- ShellViewModel.cs
-- WPF GUI Project [Caliburn.Micro] Referenced
--- [Views] Folder
---- LogEntryView.xaml
---- ShellView.xaml
所以,我有 2 个项目,一个带有模型,一个带有 ViewModels 和视图; 这是我的引导程序:
public class AppBootstrapper : BootstrapperBase
{
private CompositionContainer container;
public AppBootstrapper()
{
Initialize();
}
protected override void BuildUp(object instance)
{
this.container.SatisfyImportsOnce(instance);
}
/// <summary>
/// By default, we are configured to use MEF
/// </summary>
protected override void Configure()
{
var config = new TypeMappingConfiguration
{
DefaultSubNamespaceForViews = "WPFGUI.Views",
DefaultSubNamespaceForViewModels = "ClassLibrary.ViewModels"
};
ViewLocator.ConfigureTypeMappings(config);
ViewModelLocator.ConfigureTypeMappings(config);
var catalog =
new AggregateCatalog(
AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>());
this.container = new CompositionContainer(catalog);
var batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new WindowManager());
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue(this.container);
batch.AddExportedValue(catalog);
this.container.Compose(batch);
}
protected override IEnumerable<object> GetAllInstances(Type serviceType)
{
return this.container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
}
protected override object GetInstance(Type serviceType, string key)
{
var contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
var exports = this.container.GetExportedValues<object>(contract);
if (exports.Any())
{
return exports.First();
}
throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
var startupTasks =
GetAllInstances(typeof(StartupTask))
.Cast<ExportedDelegate>()
.Select(exportedDelegate => (StartupTask)exportedDelegate.CreateDelegate(typeof(StartupTask)));
startupTasks.Apply(s => s());
DisplayRootViewFor<IShell>();
}
}
现在,当我尝试使用绑定到列表框的 LogEntryModel 时,我收到 Cannot find view for ClassLibrary.Models.LogEntryModel.
- 我假设我需要“告诉”Caliburn 在我的类库项目中寻找模型(如何)
- 我应该在我的类库中引用 Caliburn.Micro 吗? (因为它是 GUI 的东西?)
- 我的 ViewModel 应该在 ClassLibrary 还是 GUI 项目中?
[编辑] 我改变了我的文件夹结构,我的虚拟机和模型现在组合在一起, 我更新了 bootstrapper.cs:
var config = new TypeMappingConfiguration
{
DefaultSubNamespaceForViews = "WPFGUI.Views",
DefaultSubNamespaceForViewModels = "ClassLibrary.ViewModels"
};
ViewLocator.ConfigureTypeMappings(config);
ViewModelLocator.ConfigureTypeMappings(config);
ShellViewModel 仍然有效;但 LogEntryModel 仍然显示:
Cannot find view for ClassLibrary.Models.LogEntryModel.
[编辑 2] LogEntryModel:
public class LogEntryModel
{
//GUID
public Guid GUID { get; set; }
//The log message string
public string Message { get; set; }
//The module that created the logentry (see enums Module for options)
public int Module { get; set; }
//The urgency (used for coloring: 0 = black (normal), 1 = red (error), 2 = cyan (info)
public int Severity { get; set; }
//User that triggered the logentry
public string UserID { get; set; }
//The datetime of the logentry
public DateTime LogEntryDateTime { get; set; }
}
LogEntryViewModel:
public class LogEntryViewModel
{
//This is for testing purposes only (I'd expect "Hello World" everywhere
public String Message { get; set; } = "Hello World";
}
LogEntryView.xaml:
<UserControl x:Class="ServicesUI_WPF.Views.LogEntryView"
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:WPFGUI.Views"
DataContext="ClassLibrary.ViewModels.LogEntryViewModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="Red">
</Grid>
</UserControl>
【问题讨论】:
-
LogEntryModel 与视图无关,它的视图模型调用视图...所以 Logentry 的视图和视图模型的名称是什么。 caliburn 的规则是:LogentryView 和 LogViewModel。所以如果它的规则不一样,是的,你必须指出 caliburn。
-
我是否正确理解 ViewModel 也需要存在?我认为,就我能够谷歌而言,问题在于名称空间。但是他们都在谈论将 VM 从 V 中分离出来,而不是将 M 从 VM 和 V 中分离出来,我应该将我的 VM 移动到我的模型项目并以这种方式解决问题吗?
-
我看不到您的逻辑,请查看我的答案并阅读链接。 ViewModel 和 View 存在该规则,是的,您可以在同一个库中拥有 VM 和 V,而在其他库中拥有模型...我在您的描述中没有看到视图模型...显示更多代码... Shellviewmodel 和 logentryviewmodel
-
你应该展示你的代码shellviewmodel和logentryviewmodel,以避免浪费时间
-
我想你已经在 logentryview.xaml 中引用了库模型?
标签: c# wpf caliburn.micro