Проблема с записью параметра в приложении WPF MVVM

Автор Тема: Проблема с записью параметра в приложении WPF MVVM  (Прочитано 3828 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн user32Автор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Всем привет.
Пытаюсь освоить WPF с применением паттерна MVVM, делаю простую надстройку. Идея этой надстройки следующая. Я беру элемент, вывожу его параметры в DataGrid, потом выбираю нужный мне параметр и по нажатии кнопки записываю в него значение.
В принципе получить параметр, вывести в DataGrid и получить выбранный параметр у меня получилось, но проблема возникла когда я захотел записать значение в выбранный параметр. Оно просто не записывает. Как я понял, нужно использовать для этого IExternalEventHandler, пробую через него, но тоже никак не получается или я его не правильно применяю, никак не могу разобраться.
Подскажите, как правильно нужно выполнить метод, который бы записывал параметр?
Пример, по которому я делал вот--> https://mathcadbimthingy.wordpress.com/2018/08/15/revit-classes-and-wpf-the-first-m-in-mvvm/
На всякий случай прикрепляю свой проект в VS, вдруг кто захочет глянуть и покритиковать, буду рад) https://yadi.sk/d/rQa8nF0LlOjH7Q
Заранее спасибо!

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Не открывая проект: поменяйте window.Show(), на window.ShowDialog()

Оффлайн user32Автор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Сейчас стоит как раз ShowDialog()

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Так как до компа мне ещё далеко, то выдвину ещё предположение: изменение происходит в транзакции?

Оффлайн user32Автор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Да, в транзакции. Отдельно этот метод проверял, он норм сработал, а вот приложении не хочет чет.

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Очевидно, что ничего не происходит так как ничего не вызывается



Оффлайн user32Автор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
да, этот метод я пока не вызывал (забыл удалить из примера). Сейчас там есть метод TEST, я его вызываю, в котором создаю экземпляр класса EventHandlerClass, который наследуется от интерфейса IExternalEventHandler, а в нем уже пробую делать тестовую запись в методе Execute

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Запустить проект я не смог - мне просто выдало кучу NullReferenceException. Разбираться тоже как-то не хочется.
Вижу во вьюмоделе команду:
Код - C# [Выбрать]
  1. public ICommand CommandButton
  2. {
  3.     get
  4.     {
  5.         if (_command == null)
  6.             _command = new RelayCommand((o =>RevitModelClass.TEST()));
  7.         return _command;
  8.     }
  9. }
Но в упор не вижу где она привязана к кнопке в окне и как она вызывается. Т.е. она не вызывается. А значит и ваш метод TEST() тоже не вызывается.
ExternalEvent нужен только если вы создаете немодальное окно, работающее в отдельном потоке. Если делаете модальное (ShowDialog), то ExternalEvent нафиг не нужен

Оффлайн user32Автор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
хым, печально.
имеется в ввиду в XAML? Если да, то вызываю это команду через
Код - XML [Выбрать]
  1. Command="{Binding CommandButton}
Код - XML [Выбрать]
  1. <Button Grid.Column="1" Grid.Row="1" Margin="10,10,10,10" Content="Выполнить" FontSize="16" Click="ButtonBase_OnClick" Command="{Binding CommandButton}"/>
в MainWindow.xaml

Оффлайн user32Автор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
Там я сначала пытался через MVVMLight делать, потом от них отказался, но ссылки висят, может из-за этого

Отмечено как Решение user32 28-02-2019, 11:12:13

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Эххх.... заставили все-таки посмотреть))
Итак, первое: вот тут вы использовали using
Код - C# [Выбрать]
  1. using (MainWindow view = new MainWindow())
  2. {
  3.     WindowInteropHelper helper = new WindowInteropHelper(view);
  4.     helper.Owner = proc.MainWindowHandle;
  5.     view.DataContext = vm;
  6.     view.Show();
  7. }
А в коде окна написали вот так:
Код - C# [Выбрать]
  1. public void Dispose()
  2. {
  3.     this.Close();
  4. }
Таким образом вызывается окно и тут-же закрывается  :D

Поменял на ShowDialog() - смог хотя бы увидеть окно.

Далее: метод ваш вызывается и срабатывает. Единственное, что я поменял - заменил TaskDialog на MessageBox:
Код - C# [Выбрать]
  1. using (Transaction tr = new Transaction(doc))
  2. {
  3.     tr.Start("TEST");
  4.  
  5.     foreach (Element el in enumElements)
  6.     {
  7.         try
  8.         {
  9.             el.LookupParameter("Комментарии").Set("DASHOTAKOE");
  10.         }
  11.         catch (Exception e)
  12.         {
  13.             MessageBox.Show(e.Message);
  14.         }
  15.     }
  16.     tr.Commit();
  17. }
Не знаю точно в чем взаимосвязь, но при использовании TaskDialog что-то шло не так. Но тут я могу ошибаться

Ну и самое главное - как вы хотели проверить работу, пытаясь записать в какой-то параметр TEST, которого скорее всего не существует? Еще и без проверки на null! Достаточно поставить один символ ? и сразу станет лучше:

Код - C# [Выбрать]
  1. el.LookupParameter("Комментарии")?.Set("DASHOTAKOE");




Оффлайн user32Автор темы

  • ADN OPEN
  • **
  • Сообщений: 87
  • Карма: 0
ХОХ! Спасибо большое, все заработало