Создание прогресс бара

Автор Тема: Создание прогресс бара  (Прочитано 21899 раз)

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

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Re: Создание прогресс бара
« Ответ #30 : 06-04-2021, 19:59:12 »
Никакого умысла или специального использования не было
Методы Add() и Open() для DocumentCollection acDocMgr = Application.DocumentManager;
на самом деле это методы расширения описанные в классе DocumentCollectionExtension и у меня они на прямую почему то не работают =(

Я просматривал методы и свойства класса DocumentCollection и там единственный метод на открытие документа это AppContextOpenDocument(), соответственно, выкручивался как мог.

Но по твоей наводке сейчас углубился в этот момент и попробовал заменить
Код - C# [Выбрать]
  1.       acDocMgr.AppContextOpenDocument(outPutDWG);
  2.       App.Document docA = App.Application.DocumentManager.MdiActiveDocument;
на
Код - C# [Выбрать]
  1.       App.Document docA = App.DocumentCollectionExtension.Open(acDocMgr, outPutDWG, false);
  2.       App.Application.DocumentManager.MdiActiveDocument = docA;
Поведение программы визуально не изменилось и работать с прогресс баром так же отказывается.

Разница этих функций, как я понял, для моего случая не сильно велика:
Open() - открыть указанный чертеж и вернуть документ
AppContextOpenDocument() - функция разрешающая синхронный доступ к операции открытия чертежа. Работает только в контексте приложения.

ЗЫ.
Порадовало описание метода AppContextRecoverDocument():
Цитировать
This is AppContextRecoverDocument, a member of class DocumentCollection.
Для чего, почему

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание прогресс бара
« Ответ #31 : 06-04-2021, 20:23:21 »
ЗЫ.
Порадовало описание метода AppContextRecoverDocument():
Цитировать

    This is AppContextRecoverDocument, a member of class DocumentCollection.

Для чего, почему

Как обычно смотрим откуда растут ноги:



Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Создание прогресс бара
« Ответ #32 : 06-04-2021, 20:26:17 »
На всякий случай Win7x64 и ADT 2017.
Вполне возможно, что это баг в этой версии или то, что это не чистый AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Создание прогресс бара
« Ответ #33 : 06-04-2021, 23:06:37 »
Если есть желание, можешь попробовать такой прогрессбар. Как он работает я показывал во втором видео сообщения #4 этой темы. Только тут он адаптирован под использование в Revit, надо метод вызова заменить на автокадовский Application.ShowModelessWindow. Может ещё что-то по мелочи подправить.
Код - XML [Выбрать]
  1. <Window x:Class="Support.ProgressMeterWindow"
  2.        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.        SizeToContent="WidthAndHeight"      
  5.        WindowStartupLocation="CenterScreen" ResizeMode="NoResize"
  6.        ShowInTaskbar="False" Focusable="False" IsHitTestVisible="False"
  7.        IsTabStop="False" ShowActivated="False" WindowStyle="None"
  8.        AllowsTransparency="True" x:Name="ThisControl">
  9.     <Border BorderThickness="1" BorderBrush="DarkGray" CornerRadius="2">
  10.         <StackPanel Margin="10">
  11.             <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
  12.                 <TextBlock Text="{Binding ElementName=ThisControl, Path=Header, Mode=OneWay}"/>                
  13.             </StackPanel>
  14.             <Grid Margin="0,5,0,0"><ProgressBar VerticalAlignment="Center"
  15.            Name="pBar" Width="300" Height="17"
  16.            Maximum="{Binding Maximum, Mode=OneWay}"
  17.            Value="{Binding Value, Mode=OneWay}"/>
  18.                 <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
  19.                     <TextBlock Text="{Binding ElementName=pBar, Path=Value}"/>
  20.                     <TextBlock Text=" / "></TextBlock>
  21.                     <TextBlock Text="{Binding ElementName=pBar, Path=Maximum}"/>
  22.                 </StackPanel>
  23.             </Grid>
  24.         </StackPanel>
  25.     </Border>
  26. </Window>
Код - C# [Выбрать]
  1. using System.ComponentModel;
  2. using System.Windows;
  3.  
  4. namespace Support
  5. {
  6.     /// <summary>
  7.     /// Interaction logic for ProgressMeter.xaml
  8.     /// </summary>
  9.     public partial class ProgressMeterWindow : Window, INotifyPropertyChanged
  10.     {
  11.         int _maximum, _value;
  12.         string _header;
  13.  
  14.         public string Header
  15.         {
  16.             get => _header;
  17.             set
  18.             {
  19.                 _header = value;
  20.                 OnPropertyChanged(nameof(Header));
  21.             }
  22.         }
  23.  
  24.         public int Maximum
  25.         {
  26.             get => _maximum;
  27.             set
  28.             {
  29.                 _maximum = value;
  30.                 OnPropertyChanged(nameof(Maximum));
  31.             }
  32.         }
  33.         public int Value
  34.         {
  35.             get => _value;
  36.             set
  37.             {
  38.                 this._value = value;
  39.                 OnPropertyChanged(nameof(Value));
  40.                 System.Windows.Forms.Application.DoEvents();
  41.             }
  42.         }
  43.  
  44.         public ProgressMeterWindow()
  45.         {            
  46.             InitializeComponent();
  47.             this.DataContext = this;
  48.         }
  49.  
  50.         public ProgressMeterWindow(string header, int maximum) : this()
  51.         {
  52.             Header = header;
  53.             Maximum = maximum;
  54.             Show();
  55.             System.Windows.Forms.Application.DoEvents();
  56.         }
  57.  
  58.         public void Increment()
  59.         {
  60.             Value += 1;
  61.             System.Windows.Forms.Application.DoEvents();
  62.         }
  63.  
  64.         public event PropertyChangedEventHandler PropertyChanged;
  65.  
  66.         void OnPropertyChanged(string prop)
  67.         {
  68.             PropertyChanged?.Invoke
  69.                 (this, new PropertyChangedEventArgs(prop));
  70.         }
  71.     }
  72. }

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 546
  • Карма: 119
Re: Создание прогресс бара
« Ответ #34 : 07-04-2021, 08:05:01 »
Может ещё что-то по мелочи подправить.
Основная беда прогресс баров, это избыточный вызов методов Value += 1; и как следствие перерисовки прогресс баров, это дорогостоящая операция и DoEvents(); для отображения обновления.
Как следствие, при использовании прогресс бара может сильно проседать производительность цикла. Зависит от значения maximum.


Я использую стандартный ProgressMeter(У меня то он работает :-D )
В нем небольшой алгоритм уменьшения количества вызовов Value и DoEvents().
Полезен при больших циклах > 100000, на маленьких циклах я ProgressMeter не использую.

Код - C# [Выбрать]
  1. public class UiProgressBar : IDisposable
  2. {
  3.         private ProgressMeter progressMeter = new ProgressMeter();
  4.         private int currentValue = 0;
  5.         private readonly float step;
  6.         private int progressBarProcent = 0;
  7.  
  8.         public UiProgressBar(string message, int max)
  9.         {
  10.                 progressMeter.Start(message);
  11.                 progressMeter.SetLimit(100);
  12.                 step = max / 100f;
  13.         }
  14.  
  15.  
  16.  
  17.         public void Progress()
  18.         {
  19.                 currentValue++;
  20.                 int currentProcent = (int)(currentValue / step);
  21.                 if (currentProcent != progressBarProcent)
  22.                 {
  23.                         progressMeter.MeterProgress();
  24.                         progressBarProcent = currentProcent;
  25.                         System.Windows.Forms.Application.DoEvents();//Чтобы не зависал интерфейс
  26.                 }
  27.         }
  28.  
  29.  
  30.  
  31.         public void Stop()
  32.         {
  33.                 progressMeter.Stop();
  34.                 progressMeter.Dispose();
  35.                 progressMeter = null;
  36.         }
  37.  
  38.  
  39.  
  40.         public void Dispose()
  41.         {
  42.                 Stop();
  43.         }
  44. }


Использовать как-то так:
Код - C# [Выбрать]
  1. int blockCount = 1231354;
  2. using (UiProgressBar progressBar = new UiProgressBar("Считывание блоков", blockCount))
  3. {
  4.         for (int i = 0; i < blockCount; i++)
  5.         {
  6.                 progressBar.Progress();
  7.         }
  8. }

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Re: Создание прогресс бара
« Ответ #35 : 07-04-2021, 08:56:30 »
Коллеги, искренне спасибо за примеры кода.
Я попробовал оба варианта и честно говоря думал, что пример Димы Загорулькина точно заработает, но увы, у меня так и не получилось.

Хотя если отдельно и без редактирования блоков запускать  прогресс бар, то все работает
Код - C# [Выбрать]
  1.   [Rtm.CommandMethod("zzz", Rtm.CommandFlags.Session)]
  2.   static public void zzz()
  3.   {
  4.     var pm = new ProgressMeterWindow("Редактирование блоков", 30);
  5.     App.Application.ShowModelessWindow(pm);
  6.     for (int i = 0; i < 30; i++)
  7.     {
  8.       System.Threading.Thread.Sleep(1000);
  9.       pm.Increment();
  10.     }
  11.     pm.Close();
  12.   }

Видимо это какой то глюк именно моей версии или системы в целом.
Винда то установлена лет 5 назад и аптайм около месяца, потом после перезагрузки попробую еще....

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Создание прогресс бара
« Ответ #36 : 07-04-2021, 09:19:12 »
А вот эту тему смотрел: https://adn-cis.org/forum/index.php?topic=7829.0 ?

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Re: Создание прогресс бара
« Ответ #37 : 07-04-2021, 09:34:26 »
Сейчас посмотрел мельком... вечером еще посмотрю подробнее, но пока у меня нет блоков с атрибутами, пока у дин блоков нет ручек, просто набор свойств и я очень внимательно отношусь к открытию-закрытию объектов и стараюсь открывать и использовать объекты минимально возможное время и по одному за раз.