Как передать список выделенных объектов из ЛОЦМАНА в плагин и получить их id

Автор EinRoterStern, 05.03.25, 10:16:38

« назад - далее »

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

EinRoterStern

Добрый день!

Пишу плагин на C# для Лоцман:PLM и столкнулся с проблемой. Когда я выделяю несколько объектов в Лоцмане и хочу получить их данные (id и тип объекта), я использую интерфейс IContent и метод SelectedByIndex. Однако этот метод возвращает необработанный COM-объект. Возможно ли как-то получить свойства этого объекта, например, его id? Нужно ли приводить его к другому интерфейсу или есть другой способ?

Код забора выбранных объектов:
private async void test_ClickAsync(object sender, RoutedEventArgs e)
{
    try
    {
        var objects = await GetSelectedObjectsFromActiveWindowAsync();

        if (objects == null || objects.Count == 0)
        {
            MessageBox.Show("Не удалось получить выбранные объекты!", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            return;
        }
        MessageBox.Show($"{objects.Count}");
        List<int> validObjectIds = new List<int>();

        foreach (var obj in objects)
        {
            if (obj == null) continue;


            try
            {
                // Динамически достаем ID и тип объекта

                int objId = (int)obj.ID;
                string typeName = (string)obj.TypeName;

                if (!draggedObjects.Any(o => o.ID == objId))
                {
                    if (typeName == "Сборочная единица" || typeName == "Деталь")
                    {
                        draggedObjects.Add(obj);
                        validObjectIds.Add(objId);

                        Dispatcher.Invoke(() =>
                        {
                            ObjectList.Items.Add(typeName + " - " + objId);
                            GetObjectDataAsynс();
                        });
                    }
                    else
                    {
                        MessageBox.Show($"Неверный тип объекта: {typeName}\nОбъект пропущен.", "Предупреждение", MessageBoxButton.OK, MessageBoxImage.Warning);
                    }
                }
            }
            catch (RuntimeBinderException)
            {
                MessageBox.Show("Ошибка: объект не содержит нужных свойств (ID или TypeName).", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            }

        }

        MessageBox.Show($"Обработано объектов: {validObjectIds.Count}", "Успех", MessageBoxButton.OK, MessageBoxImage.Information);
    }
    catch (Exception ex)
    {
        MessageBox.Show($"Ошибка при обработке объектов: {ex.Message}", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}


private async Task<List<dynamic>> GetSelectedObjectsFromActiveWindowAsync()
{
    return await Task.Run(() =>
    {
        try
        {
            List<dynamic> selectedObjects = new List<dynamic>();

            // Получаем интерфейс приложения
            var app = LConnection.PluginCall as ILoodsmanApplication;
            if (app != null && app.ActiveWindow != null)
            {
                var content = app.ActiveWindow.Content as IContent;
                if (content != null && content.SelectedCount > 0)
                {
                    for (int i = 0; i < content.SelectedCount; i++)
                    {
                        dynamic obj = content.SelectedByIndex(i);
                        if (obj != null)
                        {
                            selectedObjects.Add(obj);
                        }
                        else
                        {
                            MessageBox.Show("Объект пустой (null)", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Нет выбранных объектов в активном окне.", "Информация", MessageBoxButton.OK, MessageBoxImage.Information);
                }
            }
            else
            {
                MessageBox.Show("Не удалось получить активное окно ЛОЦМАН.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            return selectedObjects;
        }
        catch (Exception ex)
        {
            MessageBox.Show($"Ошибка при получении выбранных объектов: {ex.Message}", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            return new List<dynamic>();
        }
    });
}


Chipollino

Я не реализовывал асинхронную работу, но для списка выделенных в дереве объектов есть функция CGetTreeSelectedIDs вызываемая у IPluginCall

EinRoterStern

Цитата: Chipollino от 05.03.25, 11:04:23CGetTreeSelectedIDs
А в какой версии ЛОЦМАНА добавили эту функцию? Просто не могу найти это свойство в методичке

EinRoterStern

Функцию нашел, только не понимаю как ее использовать, точнее как вызвать, можете пожалуйста написать пример ее вызова и получения id

Chipollino

В метод RunMethod интерфейса IPluginCall отправляете название функции и получаете строку с разделителем ","
string IDs = PluginCall.RunMethod("CGetTreeSelectedIDs", args);
+ Благодарностей: 1

EinRoterStern

+ Благодарностей: 1

Chipollino

Цитата: EinRoterStern от 05.03.25, 12:58:55А что нужно передавать в параметры?
Данная функция не ждёт на вход параметры, поэтому пустой массив
object[] args = { };
+ Благодарностей: 2