我正在研究Revit的加载项,并希望使用mvvm light。我的问题是该程序运行我的DLL并且我没有app.xaml来声明viewmodellocator的单例作为应用程序的资源,将此声明为资源的最佳方法是什么?
Revit将我的代码作为在我的解决方案中实现IExternalCommand接口的单独类中声明的命令运行。我可以在调用MainWindow之前从代码中设置此资源吗?或者我可以将其设置为mainwindow.xaml的资源吗?
EDITED
到目前为止,我们已经编写了代码belov,但是我们在第一次运行命令时遇到错误,但第二次使用该命令时没有错误。
命令类CheckerCommand.cs
中的示例代码[Transaction(TransactionMode.Manual)]
public class CheckerCommand : IExternalCommand
{
#region IExternalCommand Members Implementation
public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements)
{
new ViewModelLocator();
MainWindow window = new MainWindow(revit);
try
{
WindowInteropHelper helper = new WindowInteropHelper(window)
{
Owner = Autodesk.Windows.ComponentManager.ApplicationWindow
};
window.ShowDialog();
return Result.Succeeded;
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
// Element selection cancelled.
return Result.Cancelled;
}
catch (Exception e)
{
message = e.ToString();
try
{
MessageBox.Show(message, "Fatal error");
window.Close();
}
catch
{
return Result.Failed;
}
return Result.Succeeded;
}
}
#endregion
}
以下是MainWindow.xaml上的一些示例代码
<Window x:Class="QMChecker.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:QMChecker.Views"
xmlns:vm="clr-namespace:QMChecker.ViewModel"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mvvm="http://www.galasoft.ch/mvvmlight"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
Title="QMChecker" Height="700" Width="1200">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/QMChecker;component/Resources/CombinedResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<vm:ViewModelLocator x:Key="Locator"/>
</ResourceDictionary>
</Window.Resources>
<Window.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"/>
</Window.DataContext>
</Window>
来自代码隐藏的MainWindow.xaml.cs的示例代码
public partial class MainWindow : Window
{
public MainWindow(ExternalCommandData _revit)
{
try
{
InitializeComponent();
}
catch (Exception e)
{
throw e;
}
ServiceLocator.Current.GetInstance<MainViewModel>().Revit = _revit;
}
}
ViewModelLocator.cs的示例代码
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
///
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<SpatialContainmentViewModel>();
SimpleIoc.Default.Register<SpatialContainmentDemandViewModel>();
SimpleIoc.Default.Register<RunChecksViewModel>();
SimpleIoc.Default.Register<SpatialContainmentParameterSummaryViewModel>();
}
public MainViewModel Main { get { return ServiceLocator.Current.GetInstance<MainViewModel>(); } }
public SpatialContainmentViewModel SpatialContainment { get { return ServiceLocator.Current.GetInstance<SpatialContainmentViewModel>(); } }
public SpatialContainmentDemandViewModel SpatialContainmentDemand { get { return ServiceLocator.Current.GetInstance<SpatialContainmentDemandViewModel>(); } }
public RunChecksViewModel RunChecks { get { return ServiceLocator.Current.GetInstance<RunChecksViewModel>(); } }
public SpatialContainmentParameterSummaryViewModel SpatialContainmentParameterSummary { get { return ServiceLocator.Current.GetInstance<SpatialContainmentParameterSummaryViewModel>(); } }
public static void Cleanup()
{
SimpleIoc.Default.Unregister<MainViewModel>();
SimpleIoc.Default.Unregister<SpatialContainmentViewModel>();
SimpleIoc.Default.Unregister<SpatialContainmentDemandViewModel>();
SimpleIoc.Default.Unregister<RunChecksViewModel>();
SimpleIoc.Default.Unregister<SpatialContainmentParameterSummaryViewModel>();
}
}
我必须在每个UserControl上使用ResourceDictionary
<UserControl.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator"/>
</ResourceDictionary>
</UserControl.Resources>
答案 0 :(得分:0)
我知道有个老问题,但是经过一番搜索,我没有在其他地方找到答案。我只是部分工作了,这就是我所拥有的:
MainWindow.xaml.cs
...
public MainWindow()
{
Resources.Add("Locator", new ViewModelLocator());
InitializeComponent();
}
...
MainWindow.xaml
<Window
...
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:AppleCMS.ModelHarvesterAddin"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ResourceDictionary>
<local:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</ResourceDictionary>
</Window.Resources>
...
其余是MVVMLight的标准配置。我认为关键在于代码背后的Resources.Add("Locator", new ViewModelLocator());
。
这在运行插件时有效。看起来MVVMLight的设计时数据似乎还行不通。我还没有添加多个视图,但是我怀疑在每个视图中都需要以上视图。