是否必须使用WPF和MVVM模式将Revit命令作为中继命令传递

c9x0cxw0  于 2023-05-19  发布在  其他
关注(0)|答案(1)|浏览(126)

我有几个外部命令,在Revit中通过下拉按钮调用时可以完美地工作。我试图通过使用MVVM模式在WPF窗口中创建一个命令列表来升级代码-主要是。在这些情况下没有模型,而是与Revit文件通信的服务。以下是服务执行调用以移除材料的示例:

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

namespace DevTools.Services.Cleaner
{
    [Transaction(TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    [Journaling(JournalingMode.NoCommandData)]
    public class PurgeAllMaterialsService : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            var uiDoc = commandData.Application.ActiveUIDocument;
            var doc = uiDoc.Document;
        try
        {
            using Transaction trans = new(doc, "Delete all materials");

            var allMaterials = new FilteredElementCollector(doc)
                .OfClass(typeof(Material))
                .ToElementIds();

            var count = 0;

            trans.Start();
            foreach (var id in allMaterials)
            {
                try
                {
                    var m = doc.GetElement(id) as Material;
                    {
                        uiDoc.Document.Delete(id);
                        count++;
                    }
                }
                catch (Exception ex)
                {
                    message = ex.Message;
                    return Result.Failed;
                }
            }
            trans.Commit();
            TaskDialog.Show("Delete All Materials", count + " materials have been deleted");
            return Result.Succeeded;
        }
        catch (Autodesk.Revit.Exceptions.OperationCanceledException)
        {
            return Result.Cancelled;
        }
        catch (Exception ex)
        {
            message = ex.Message;
            return Result.Failed;
        }
    }
}
}

视图模型将服务传递给命令

using DevTools.Services.Cleaner;

namespace DevTechTools.ViewModels
{
    public class CleanerViewModel
    {
        public PurgeAllMaterialsService PurgeMaterialCommand { get; }
        public CleanerViewModel(PurgeAllMaterialsService purgeAllMaterials)
        {
            PurgeMaterialCommand = new PurgeAllMaterialsService();
        }
    }
}

并且命令将服务传递给视图。

using DevTools.Views;
using Nice3point.Revit.Toolkit.External;

namespace DevTechTools.Commands
{
    [UsedImplicitly]
    [Transaction(TransactionMode.Manual)]
    public class CleanWindowCommand : ExternalCommand
    {
        public override void Execute()
        {
            var pm = new PurgeAllMaterialsService();

            var viewModel = new CleanerViewModel(pm);
            var view = new CleanerPage(viewModel);
            view.ShowDialog();
        }
    }
}

在视图中,命令由类似于这样的按钮调用。

<Button Content="Purge Materials"
        Command="{Binding PurgeMaterialCommand, Mode=OneWay}"
        Width="200"
        Height="28"
        Margin="0,10,0,0"
        BorderBrush="Transparent"
        Background="{StaticResource HeaderBackgroundBrush}"
        Foreground="{StaticResource LightBrush}" />

问题是按钮不执行命令。缺少什么?WPF窗口是否阻止命令发送?

rggaifut

rggaifut1#

ButtonCommand属性必须设置或绑定到实现System.Windows.Input.ICommand接口的对象。
因此,视图模型的PurgeMaterialCommand属性应该返回ICommand实现。然后,当您通过单击按钮调用命令时,将调用Execute(object parameter)方法。

相关问题