为什么我尝试使用MVVM WPF中的命令修改视图模型中对象的空错误?

问题描述 投票:0回答:1

我有一个奇怪的情况,我无法弄清楚。我正在使用MVVM构建从商业软件使用OAPI的程序。我在视图模型中创建了该API的公共字段。然后创建了两个方法,并使用命令将它们绑定到UI中的两个按钮。一种方法负责连接到API,另一种方法负责从商业软件检索数据。第一种方法可以完成工作并与软件建立连接。但是,当我调用第二条命令来检索数据时,出现一个错误,提示您的对象为空。当我再次使用fist命令时,它表示我们已经连接,这意味着我的对象不是null。但第二种方法仍然出现错误。所有方法都是公共的,并且在视图模型中定义。

两个方法都被命令调用

我看不到我在哪里犯错。如果有人可以帮助我,我将不胜感激。最好的问候

在视图模型中,我定义了OAPI所需的这些属性

//dimension the ETABS Object as cOAPI type
    public ETABSv1.cOAPI myETABSObject { get; set; }
    public ETABS2016.cOAPI myETABSObject16 { get; set; }
    public ETABSv1.cSapModel mySapModel { get; set; }
    public ETABS2016.cSapModel mySapModel16 { get; set; }

这是我的Cammand课程:

internal class GetStoryDataFromEtabsCommand : ICommand
{
    private MainWindowViewModel _viewModel;
    public GetStoryDataFromEtabsCommand(MainWindowViewModel viewModel)
    {
        _viewModel = viewModel;
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _viewModel.GetStoryDataFromEtabs();
    }
}

还有另一个与上面完全一样的命令,但是调用了ConnectToEtabs()方法

这是我的ConnectToEtabs()方法:

public void ConnectToEtabs()
{
    //get the active ETABS object
    myETABSObject16 = 
    (ETABS2016.cOAPI) System.Runtime.InteropServices.Marshal.GetActiveObject 
    ("CSI.ETABS.API.ETABSObject");
    //Get a reference to cSapModel to access all API classes and functions
    mySapModel16 = myETABSObject16.SapModel;
}

这是我的GetStoryDataFromEtabs()方法:

public void GetStoryDataFromEtabs()
{
   double BaseElev = 0;
   string[] notneededst = null;
   int NumOfStory = 0;
   double[] storyElev = null;
   double[] notneededd = null;
   Boolean[] notneededbool = null;
   int[] notneededint = null;
   ret = mySapModel16.Story.GetStories(ref NumOfStory, ref notneededst, ref 
         storyElev, ref notneededd, ref notneededbool, ref notneededst, ref 
         notneededbool, ref notneededd);
   earthQuake.NumberOfStory = NumOfStory;
   earthQuake.BuildingHeight = Math.Round((storyElev[NumOfStory] - 
   storyElev[0]), 2);
}

在GetStoryDataFromEtabs()方法中,mySapModel16为null。另一件事:来自不同用户控件的不同按钮正在使用每个命令。

c# wpf mvvm command
1个回答
-1
投票

非常纠结/不完整的代码示例。但是我将尝试以对我友好的实现方式进行突破。我没有确切的解决方案,但是没有什么建议。

我建议使用RelayCommand中的here类。

RelayCommand.cs-只需将其添加到项目中一次,然后就忘了:)

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Func<object, bool> _canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter) => _canExecute == null || _canExecute(parameter);
    public void Execute(object parameter) => _execute(parameter);
}

然后使用ViewModel中的用法

private ICommand _getStoryDataFromEtabsCommand;

public ICommand GetStoryDataFromEtabsCommand
    => _getStoryDataFromEtabsCommand ?? (_getStoryDataFromEtabsCommand = new RelayCommand(parameter =>
    {
        GetStoryDataFromEtabs();
    }));

标记

<Button Content="Click me!" Command="{Binding GetStoryDataFromEtabsCommand}"/>

下一个建议是使用断点进行调试。

设置断点:

    mySapModel16 = myETABSObject16.SapModel;
} // <== here

然后检查mySapModel16是否为null。如果是,则表示myETABSObject16.SapModel也为null。然后探索,为什么。

如果以上所有都成功通过,请设置下一个断点

ret = mySapModel16.Story.GetStories(...); // <== here

然后再次检查null

© www.soinside.com 2019 - 2024. All rights reserved.