- UID
- 14
- 积分
- 8264
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-1-4
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
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.
- using System;
- using Autodesk.Windows;
- using Autodesk.AutoCAD.Runtime;
- using Autodesk.AutoCAD.Windows;
- using Autodesk.AutoCAD.EditorInput;
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.Geometry;
- using acApp = Autodesk.AutoCAD.ApplicationServices.Application;
- using System.Threading;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using WinForms = System.Windows.Forms;
- [assembly: CommandClass(typeof(TaskDialogTest.Commands))]
- [assembly: ExtensionApplication(typeof(TaskDialogTest.Module))]
- namespace TaskDialogTest
- {
- // to make the AutoCAD managed runtime happy
- public class Module : IExtensionApplication
- {
- public void Initialize()
- {
- }
- public void Terminate()
- {
- }
- }
- public class Commands
- {
- public class MyVarOverride : IDisposable
- {
- object oldValue;
- string varName;
- public MyVarOverride(string name, object value)
- {
- varName = name;
- oldValue = acApp.GetSystemVariable(name);
- acApp.SetSystemVariable(name, value);
- }
-
- public void Dispose()
- {
- acApp.SetSystemVariable(varName, oldValue);
- }
- }
- public class MyData
- {
- public int counter = 0;
- public bool delay = true;
- // since the callback data can be reused, be sure
- // to reset it before invoking the task dialog
- public void Reset()
- {
- counter = 0;
- delay = true;
- }
- }
- #region HELPER METHODS
- // helper method for processing the callback both in the
- // data-member case and the callback argument case
- private bool handleCallback(ActiveTaskDialog taskDialog,
- TaskDialogCallbackArgs args,
- MyData callbackData)
- {
- // This gets called continuously until we finished completely
- if (args.Notification == TaskDialogNotification.Timer)
- {
- // To make it longer we do some delay in every second call
- if (callbackData.delay)
- {
- System.Threading.Thread.Sleep(1000);
- }
- else
- {
- callbackData.counter += 10;
- taskDialog.SetProgressBarRange(0, 100);
- taskDialog.SetProgressBarPosition(
- callbackData.counter);
- // This is the main action - adding 100 lines 1 by 1
- Database db = HostApplicationServices.WorkingDatabase;
- Transaction tr = db.TransactionManager.TopTransaction;
- BlockTable bt = (BlockTable)tr.GetObject(
- db.BlockTableId, OpenMode.ForRead);
- BlockTableRecord ms = (BlockTableRecord)tr.GetObject(
- bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
- Line ln = new Line(
- new Point3d(0, callbackData.counter, 0),
- new Point3d(10, callbackData.counter, 0));
- ms.AppendEntity(ln);
- tr.AddNewlyCreatedDBObject(ln, true);
- // To make it appear on the screen - might be a bit costly
- tr.TransactionManager.QueueForGraphicsFlush();
- acApp.DocumentManager.MdiActiveDocument.Editor.Regen();
- // We are finished
- if (callbackData.counter >= 100)
- {
- // We only have a cancel button,
- // so this is what we can press
- taskDialog.ClickButton(
- (int)WinForms.DialogResult.Cancel);
- return true;
- }
- }
- callbackData.delay = !callbackData.delay;
- }
- else if (
- args.Notification == TaskDialogNotification.ButtonClicked)
- {
- // we only have a cancel button
- if (args.ButtonId == (int)WinForms.DialogResult.Cancel)
- {
- return false;
- }
- }
- return true;
- }
- private TaskDialog CreateTaskDialog()
- {
- TaskDialog td = new TaskDialog();
- td.WindowTitle = "Adding lines";
- td.ContentText = "This operation adds 10 lines one at a " +
- "time and might take a bit of time.";
- td.EnableHyperlinks = true;
- td.ExpandedText = "This operation might be lengthy.";
- td.ExpandFooterArea = true;
- td.AllowDialogCancellation = true;
- td.ShowProgressBar = true;
- td.CallbackTimer = true;
- td.CommonButtons = TaskDialogCommonButtons.Cancel;
- return td;
- }
- #endregion
- #region TASK DIALOG USING CALLBACK DATA ARGUMENT
- /////////////////////////////////////////////////////////////////
- // This sample uses a local instance of the callback data.
- // Since the TaskDialog class needs to convert the callback data
- // to an IntPtr to pass it across the managed-unmanaged divide,
- // be sure to convert it to an IntPtr before passing it off
- // to the TaskDialog instance.
- //
- // This case requires more code than the member-based sample
- // below, but is useful when a callback is shared
- // between multiple task dialogs.
- /////////////////////////////////////////////////////////////////
- // task dialog callback that uses the mpCallbackData argument
- public bool TaskDialogCallback(ActiveTaskDialog taskDialog,
- TaskDialogCallbackArgs args,
- object mpCallbackData)
- {
- // convert the callback data from an IntPtr to the actual
- // object using GCHandle
- GCHandle callbackDataHandle =
- GCHandle.FromIntPtr((IntPtr)mpCallbackData);
- MyData callbackData = (MyData)callbackDataHandle.Target;
- // use the helper method to do the actual processing
- return handleCallback(taskDialog, args, callbackData);
- }
- [CommandMethod("ShowTaskDialog")]
- public void ShowTaskDialog()
- {
- Database db = HostApplicationServices.WorkingDatabase;
- using (
- Transaction tr = db.TransactionManager.StartTransaction())
- {
- // create the task dialog and initialize the callback method
- TaskDialog td = CreateTaskDialog();
- td.Callback = new TaskDialogCallback(TaskDialogCallback);
- // create the callback data and convert it to an IntPtr
- // using GCHandle
- MyData cbData = new MyData();
- GCHandle cbDataHandle = GCHandle.Alloc(cbData);
- td.CallbackData = GCHandle.ToIntPtr(cbDataHandle);
- // Just to minimize the "Regenerating model" messages
- using (new MyVarOverride("NOMUTT", 1))
- {
- td.Show(Application.MainWindow.Handle);
- }
- // If the dialog was not cancelled before it finished
- // adding the lines then commit transaction
- if (memberCallbackData.counter >= 100)
- tr.Commit();
- // be sure to clean up the gc handle before returning
- cbDataHandle.Free();
- }
- }
- #endregion
- #region TASK DIALOG USING DATA-MEMBER-BASED CALLBACK DATA
-
- /////////////////////////////////////////////////////////////////
- // This sample uses a data member for the callback data.
- // This avoids having to pass the callback data as an IntPtr
- /////////////////////////////////////////////////////////////////
- // member-based callback data -
- // used with MemberTaskDialogCallback
- MyData memberCallbackData = new MyData();
- // task dialog callback that uses the callback data member;
- // does not use mpCallbackData
- public bool TaskDialogCallbackUsingMemberData(
- ActiveTaskDialog taskDialog,
- TaskDialogCallbackArgs args,
- object mpCallbackData)
- {
- // use the helper method to do the actual processing
- return handleCallback(taskDialog, args, memberCallbackData);
- }
- [CommandMethod("ShowTaskDialogWithDataMember")]
- public void ShowTaskDialogWithDataMember()
- {
- Database db = HostApplicationServices.WorkingDatabase;
- using (
- Transaction tr = db.TransactionManager.StartTransaction())
- {
- // create the task dialog and initialize the callback method
- TaskDialog td = CreateTaskDialog();
- td.Callback =
- new TaskDialogCallback(TaskDialogCallbackUsingMemberData);
- // make sure the callback data is initialized before
- // invoking the task dialog
- memberCallbackData.Reset();
- // Just to minimize the "Regenerating model" messages
- using (new MyVarOverride("NOMUTT", 1))
- {
- td.Show(Application.MainWindow.Handle);
- }
- // If the dialog was not cancelled before it finished
- // adding the lines then commit transaction
- if (memberCallbackData.counter >= 100)tr.Commit();
- }
- }
- #endregion
- }
- }
|
|