【问题标题】:Can't use windowManager.ShowWindow() with Caliburn.Micro不能将 windowManager.ShowWindow() 与 Caliburn.Micro 一起使用
【发布时间】:2019-11-07 20:54:05
【问题描述】:

我目前正在为 Revit(BIM 软件)开发一个插件,并且我正在尝试使用 WPF 和 Caliburn.Micro 在我按下插件的按钮时显示一个窗口/对话框。

就像在文档中一样,我有一个引导程序:

public class Bootstrapper : BootstrapperBase
{

    public Bootstrapper()
    {
        Initialize();
    }

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

一个简单的测试 ViewModel:

namespace ExternalForms.ViewModels
{

public class LocationPopupViewModel : Screen
{
    private int _horizontalLength;
    private int _verticalLength;

    public int HorizontalLength
    {
        get 
        { 
            return _horizontalLength; 
        }
        set 
        { 
            _horizontalLength = value;
            NotifyOfPropertyChange(() => HorizontalLength);
        }
    }

    public int VerticalLength
    {
        get 
        { 
            return _verticalLength; 
        }
        set 
        { 
            _verticalLength = value;
            NotifyOfPropertyChange(() => VerticalLength);
        }
    }
}
}

当然还有我要显示的窗口:

<Window x:Class="ExternalForms.Views.LocationPopupView"
    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:ExternalForms.Views"
    mc:Ignorable="d" WindowStartupLocation="CenterScreen"
    ResizeMode="CanResizeWithGrip"
    Title="gebied" Height="300" Width="410"
    FontSize="16">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="20"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="20"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="20"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="20"/>
    </Grid.RowDefinitions>


    <!--Row 1-->
    <TextBlock Text="Stel xxx in" FontWeight="DemiBold" Grid.Column="1" Grid.Row="1" FontSize="18"/>

    <!--Row 2-->
    <StackPanel Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Width="360" Margin="0, 0, 0, 20">
        <TextBlock TextWrapping="Wrap">
            Let op dat het gebied een maximale horizontale en verticale lengte mag hebben van 1 kilometer.
        </TextBlock>
    </StackPanel>


    <!--Row 3-->
    <TextBlock Text="Horizontaal" Grid.Column="1" Grid.Row="3"/>

    <!--Row 4-->
    <TextBox x:Name="HorizontalLength" Grid.Row="4" Grid.Column="1" MinWidth="100"/>


    <!--Row 5-->
    <TextBlock Text="Verticaal" Grid.Column="1" Grid.Row="5"/>

    <!--Row 6-->
    <TextBox x:Name="VerticalLength" Grid.Row="6" Grid.Column="1" MinWidth="100"/>


    <!--Row 7-->
    <StackPanel Orientation="Horizontal" Grid.Row="7" Grid.Column="1" Margin="0, 20, 0, 0" Grid.ColumnSpan="2" HorizontalAlignment="Right">
        <Button x:Name="SubmitDimensions" IsDefault="True" Width="100" Height="30">OK</Button>
        <Button IsCancel="True" IsDefault="True" Width="100" Height="30">Cancel</Button>
    </StackPanel>

</Grid>

试图显示窗口的函数:

        private void SetBoundingBox()
    {
        IWindowManager windowManager = new WindowManager();

        LocationPopupView locationPopup = new LocationPopupView();

        windowManager.ShowWindow(locationPopup, null, null);

    }

但是当我尝试在 Revit 中打开对话框时,会弹出一个错误窗口:

更新: 我当前的项目结构如下所示:

Assembly "UI" 负责 Revit 中的所有内部 UI 元素(因此 Revit 中的按钮,即使目前只有一个)。

Revit 中的当前按钮调用“Get3DBAG”程序集,后者执行一些任务并最终调用“Location”程序集,该程序集为“ExternalForms”程序集中的 WPF 视图调用 Windowmanager.showwindow() 方法.

【问题讨论】:

    标签: c# caliburn.micro revit-api


    【解决方案1】:

    你的问题出在下面一行。

    LocationPopupView locationPopup = new LocationPopupView();
    

    您正在尝试初始化 View 的实例,而不是 ViewModel。您应该将其替换为以下内容。

    LocationPopupViewModel locationPopup = new LocationPopupViewModel();
    

    Caliburn Micro 将使用naming convention 自行解析相应的视图。

    更新:基于评论

    根据您的评论,您的 View/ViewModel 似乎位于不同的程序集中。在这种情况下,您需要确保在 Caliburn Micro 搜索视图时包含程序集。您可以通过覆盖 Bootstrapper 中的 SelectAssemblies 方法来实现。

        protected override IEnumerable<Assembly> SelectAssemblies()
        {
            return new[] 
           {
               Assembly.GetExecutingAssembly()
              // Ensure your external assembly is included.
           };
        }
    

    您也有兴趣使用 Caliburn Micro 阅读更多 Custom Conventions

    【讨论】:

    • 您好,感谢您的评论,但我仍然遇到同样的错误。现在我得到“找不到 LocationPopupViewModel 的视图”,而不仅仅是 LocationPopupView。我在文档中找不到任何东西。我对引导程序做错了吗?
    • 或者可能是调用视图的函数在不同的命名空间中的问题?
    • 希望您的视图和视图模型位于不同的文件夹中,文件夹分别命名为视图和视图模型。另外,它们是否有机会单独组装?
    • 我有不同的文件夹模型/视图模型/视图。但是是的,视图和调用方法在不同的程序集中。
    • @Martijn 请检查更新后的答案。由于它是外部程序集,因此您需要在搜索 View/ViewModels 时指示 Caliburn Micro 包含该程序集
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 2019-02-20
    相关资源
    最近更新 更多