找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1325|回复: 0

[分享] TaskDialog with progress bar

[复制链接]

已领礼包: 593个

财富等级: 财运亨通

发表于 2013-6-12 01:48:04 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
TaskDialog with progress bar                                                                                                        By Adam Nagy
I found the ShowProgressBar property of TaskDialog, but it's not clear how I could make use of it. Any samples?
Solution
You need to assign a callback function to the TaskDialog that can be called continously so you can do parts of the lengthy process you want to show a progress bar for. Here is a sample that shows how you can do it.
As you can see it from the comments below there are issues with this on 64 bit OS. My colleague Dianne Phillips looked into it and it turned out to be some issue with assigning your own data to the TaskDialog like so:
td.CallbackData = new MyData();
Her modified code circumvents the issue in two ways: either by using a global variable or assigning your data as an IntPtr. Both ways seem to work fine on 64 bit OS as well.

  1. using System;
  2. using Autodesk.Windows;
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.AutoCAD.Windows;
  5. using Autodesk.AutoCAD.EditorInput;
  6. using Autodesk.AutoCAD.ApplicationServices;
  7. using Autodesk.AutoCAD.DatabaseServices;
  8. using Autodesk.AutoCAD.Geometry;
  9. using acApp = Autodesk.AutoCAD.ApplicationServices.Application;

  10. using System.Threading;
  11. using System.Globalization;
  12. using System.Runtime.InteropServices;
  13. using WinForms = System.Windows.Forms;  

  14. [assembly: CommandClass(typeof(TaskDialogTest.Commands))]
  15. [assembly: ExtensionApplication(typeof(TaskDialogTest.Module))]

  16. namespace TaskDialogTest
  17. {
  18.   // to make the AutoCAD managed runtime happy
  19.   public class Module : IExtensionApplication
  20.   {
  21.     public void Initialize()
  22.     {
  23.     }
  24.     public void Terminate()
  25.     {
  26.     }
  27.   }

  28.   public class Commands
  29.   {
  30.     public class MyVarOverride : IDisposable
  31.     {
  32.       object oldValue;
  33.       string varName;

  34.       public MyVarOverride(string name, object value)
  35.       {
  36.         varName = name;
  37.         oldValue = acApp.GetSystemVariable(name);
  38.         acApp.SetSystemVariable(name, value);
  39.       }



  40.       public void Dispose()
  41.       {
  42.         acApp.SetSystemVariable(varName, oldValue);
  43.       }
  44.     }
  45.     public class MyData
  46.     {
  47.       public int counter = 0;
  48.       public bool delay = true;

  49.       // since the callback data can be reused, be sure
  50.       // to reset it before invoking the task dialog
  51.       public void Reset()
  52.       {
  53.         counter = 0;
  54.         delay = true;
  55.       }
  56.     }

  57.     #region HELPER METHODS

  58.     // helper method for processing the callback both in the
  59.     // data-member case and the callback argument case
  60.     private bool handleCallback(ActiveTaskDialog taskDialog,
  61.                                 TaskDialogCallbackArgs args,
  62.                                 MyData callbackData)
  63.     {
  64.       // This gets called continuously until we finished completely
  65.       if (args.Notification == TaskDialogNotification.Timer)
  66.       {
  67.         // To make it longer we do some delay in every second call
  68.         if (callbackData.delay)
  69.         {
  70.           System.Threading.Thread.Sleep(1000);
  71.         }
  72.         else
  73.         {
  74.           callbackData.counter += 10;
  75.           taskDialog.SetProgressBarRange(0, 100);
  76.           taskDialog.SetProgressBarPosition(
  77.               callbackData.counter);

  78.           // This is the main action - adding 100 lines 1 by 1

  79.           Database db = HostApplicationServices.WorkingDatabase;
  80.           Transaction tr = db.TransactionManager.TopTransaction;
  81.           BlockTable bt = (BlockTable)tr.GetObject(
  82.             db.BlockTableId, OpenMode.ForRead);
  83.           BlockTableRecord ms = (BlockTableRecord)tr.GetObject(
  84.             bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
  85.           Line ln = new Line(
  86.             new Point3d(0, callbackData.counter, 0),
  87.             new Point3d(10, callbackData.counter, 0));
  88.           ms.AppendEntity(ln);
  89.           tr.AddNewlyCreatedDBObject(ln, true);

  90.           // To make it appear on the screen - might be a bit costly

  91.           tr.TransactionManager.QueueForGraphicsFlush();
  92.           acApp.DocumentManager.MdiActiveDocument.Editor.Regen();

  93.           // We are finished

  94.           if (callbackData.counter >= 100)
  95.           {
  96.             // We only have a cancel button,
  97.             // so this is what we can press

  98.             taskDialog.ClickButton(
  99.               (int)WinForms.DialogResult.Cancel);
  100.             return true;
  101.           }
  102.         }
  103.         callbackData.delay = !callbackData.delay;
  104.       }
  105.       else if (
  106.         args.Notification == TaskDialogNotification.ButtonClicked)
  107.       {
  108.         // we only have a cancel button
  109.         if (args.ButtonId == (int)WinForms.DialogResult.Cancel)
  110.         {
  111.           return false;
  112.         }
  113.       }
  114.       return true;
  115.     }

  116.     private TaskDialog CreateTaskDialog()
  117.     {
  118.       TaskDialog td = new TaskDialog();
  119.       td.WindowTitle = "Adding lines";
  120.       td.ContentText = "This operation adds 10 lines one at a " +
  121.                       "time and might take a bit of time.";
  122.       td.EnableHyperlinks = true;
  123.       td.ExpandedText = "This operation might be lengthy.";
  124.       td.ExpandFooterArea = true;
  125.       td.AllowDialogCancellation = true;
  126.       td.ShowProgressBar = true;
  127.       td.CallbackTimer = true;
  128.       td.CommonButtons = TaskDialogCommonButtons.Cancel;
  129.       return td;
  130.     }

  131.     #endregion
  132.     #region TASK DIALOG USING CALLBACK DATA ARGUMENT

  133.     /////////////////////////////////////////////////////////////////
  134.     // This sample uses a local instance of the callback data.
  135.     // Since the TaskDialog class needs to convert the callback data
  136.     // to an IntPtr to pass it across the managed-unmanaged divide,
  137.     // be sure to convert it to an IntPtr before passing it off
  138.     // to the TaskDialog instance.
  139.     //
  140.     // This case requires more code than the member-based sample
  141.     // below, but is useful when a callback is shared
  142.     // between multiple task dialogs.
  143.     /////////////////////////////////////////////////////////////////
  144.     // task dialog callback that uses the mpCallbackData argument

  145.     public bool TaskDialogCallback(ActiveTaskDialog taskDialog,
  146.                                     TaskDialogCallbackArgs args,
  147.                                     object mpCallbackData)
  148.     {

  149.       // convert the callback data from an IntPtr to the actual
  150.       // object using GCHandle

  151.       GCHandle callbackDataHandle =
  152.         GCHandle.FromIntPtr((IntPtr)mpCallbackData);
  153.       MyData callbackData = (MyData)callbackDataHandle.Target;

  154.       // use the helper method to do the actual processing
  155.       return handleCallback(taskDialog, args, callbackData);
  156.     }
  157.     [CommandMethod("ShowTaskDialog")]
  158.     public void ShowTaskDialog()
  159.     {
  160.       Database db = HostApplicationServices.WorkingDatabase;
  161.       using (
  162.         Transaction tr = db.TransactionManager.StartTransaction())
  163.       {
  164.         // create the task dialog and initialize the callback method
  165.         TaskDialog td = CreateTaskDialog();
  166.         td.Callback = new TaskDialogCallback(TaskDialogCallback);

  167.         // create the callback data and convert it to an IntPtr
  168.         // using GCHandle

  169.         MyData cbData = new MyData();
  170.         GCHandle cbDataHandle = GCHandle.Alloc(cbData);
  171.         td.CallbackData = GCHandle.ToIntPtr(cbDataHandle);

  172.         // Just to minimize the "Regenerating model" messages

  173.         using (new MyVarOverride("NOMUTT", 1))
  174.         {
  175.           td.Show(Application.MainWindow.Handle);
  176.         }

  177.         // If the dialog was not cancelled before it finished
  178.         // adding the lines then commit transaction

  179.         if (memberCallbackData.counter >= 100)
  180.           tr.Commit();

  181.         // be sure to clean up the gc handle before returning

  182.         cbDataHandle.Free();
  183.       }
  184.     }

  185.     #endregion
  186.     #region TASK DIALOG USING DATA-MEMBER-BASED CALLBACK DATA



  187.     /////////////////////////////////////////////////////////////////
  188.     // This sample uses a data member for the callback data.
  189.     // This avoids having to pass the callback data as an IntPtr
  190.     /////////////////////////////////////////////////////////////////

  191.     // member-based callback data -
  192.     // used with MemberTaskDialogCallback

  193.     MyData memberCallbackData = new MyData();

  194.     // task dialog callback that uses the callback data member;
  195.     // does not use mpCallbackData

  196.     public bool TaskDialogCallbackUsingMemberData(
  197.       ActiveTaskDialog taskDialog,
  198.       TaskDialogCallbackArgs args,
  199.       object mpCallbackData)
  200.     {
  201.       // use the helper method to do the actual processing
  202.       return handleCallback(taskDialog, args, memberCallbackData);
  203.     }

  204.     [CommandMethod("ShowTaskDialogWithDataMember")]
  205.     public void ShowTaskDialogWithDataMember()
  206.     {
  207.       Database db = HostApplicationServices.WorkingDatabase;
  208.       using (
  209.         Transaction tr = db.TransactionManager.StartTransaction())
  210.       {
  211.         // create the task dialog and initialize the callback method
  212.         TaskDialog td = CreateTaskDialog();
  213.         td.Callback =
  214.           new TaskDialogCallback(TaskDialogCallbackUsingMemberData);

  215.         // make sure the callback data is initialized before
  216.         // invoking the task dialog
  217.         memberCallbackData.Reset();
  218.         // Just to minimize the "Regenerating model" messages
  219.         using (new MyVarOverride("NOMUTT", 1))
  220.         {
  221.           td.Show(Application.MainWindow.Handle);
  222.         }

  223.         // If the dialog was not cancelled before it finished
  224.         // adding the lines then commit transaction
  225.         if (memberCallbackData.counter >= 100)tr.Commit();
  226.       }
  227.     }
  228.     #endregion
  229.   }
  230. }

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-17 22:32 , Processed in 0.171927 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表