Почему я получаю нулевую ошибку для моего объекта в модели представления, когда я пытаюсь изменить ее с помощью команды в MVVM WPF? - PullRequest
1 голос
/ 16 апреля 2020

У меня странная ситуация, которую я не могу понять. Я использую MVVM для создания программы, которая использует OAPI из коммерческого программного обеспечения. Я создал поле publi c этого API внутри моей view-модели. Затем я создал два метода и использую команды, чтобы связать их с двумя кнопками в моем пользовательском интерфейсе. один из методов отвечает за подключение к API, а другой - за получение данных из коммерческого программного обеспечения. Первый метод выполняет свою работу и устанавливает соединение с программным обеспечением. но когда я вызываю вторую команду для извлечения данных, я получаю сообщение об ошибке, в котором говорится, что ваш объект пуст. когда я использую команду fist еще раз, она говорит, что мы уже подключены, что означает, что мой объект не нулевой. но я все еще получаю ошибку во втором методе. все методы опубликованы c и определены внутри view-модели.

оба метода вызываются командами

Я не вижу, где я делаю ошибку. Буду признателен, если кто-нибудь сможет мне помочь. С наилучшими пожеланиями

В модели представления я определил эти свойства, которые требуются 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 является нулевым. Еще одна вещь: каждая команда используется разными кнопками из разных пользовательских элементов управления.

1 Ответ

0 голосов
/ 17 апреля 2020

Я думаю, что эта строка может быть там, где выдается ваша ошибка. Вы можете это подтвердить?

ret = mySapModel16.Story.GetStories(ref NumOfStory, ref notneededst, ref 
         storyElev, ref notneededd, ref notneededbool, ref notneededst, ref 
         notneededbool, ref notneededd);

Мои рассуждения двоякие,

  1. ref типы должны быть инициализированы до того, как они будут переданы в функции.
  2. Затем вы используете один из этих типов ссылок позже:

earthQuake.BuildingHeight = Math.Round((storyElev[NumOfStory] - storyElev[0]), 2);

Если ваша функция mySapModel16.Story.GetStories(…) инициализирует параметры, которые вы передаете ему, тогда вы должны использовать out.

С другой стороны, вы должны рассмотреть возможность реализации вашим ViewModel свойства ICommand, к которому вы привязываетесь, и заставить его запускать задачу, например

public ICommand GetStoryDataFromEtabsCommand{get;set;}
public bool IsConnected{get;private set;}

и в конструкторе

GetStoryDataFromEtabsCommand = new Command(()=>GetStoryDataFromEtabs(), ()=>IsConnected);

, где IsConnected устанавливается, когда у вас есть соединение, выполненное вашей функцией соединения.

Тогда public void GetStoryDataFromEtabs() становится public Task GetStoryDataFromEtabs(). Это позволит вам сделать функцию асинхронной и ожидать вызова mySapModel16.Story.GetStories(…), если вы обнаружите, что это занимает много времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...