.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Zoom from modal dialog

17 REPLIES 17
Reply
Message 1 of 18
sfinch1
1492 Views, 17 Replies

Zoom from modal dialog

I have an app that uses a paletteset.  The paletteset displays a modal dialog on a particular action.  From the modal dialog, the user needs to be able to click a button to zoom to a particular coordinate.  I have it all working, with one problem.  The Zoom doesn't occur until the user closes the modal dialog.  I know this is related to my limited understanding of contexts in AutoCAD, and am hoping that someone can point me in the right direction.

 

I've tried calling my Zoom method from the modal dialog, from the parent paletteset, and asynchronously using doc.SendStringToExecute() back to my main commands class, with the same result.  The Zoom occurs after exiting the modal dialog.

 

Any advice on how I can make the zoom occur while remaining in the modal dialog?

 

Thanks!

Tags (3)
17 REPLIES 17
Message 2 of 18
DiningPhilosopher
in reply to: sfinch1

You can't really get much help without showing some code, It's difficult to guess what your code is doing.

 

For example, how exactly, are you performing the ZOOM in the click handler?

Message 3 of 18

I am not sure but maybe it can help you, but if is possible for you please put your current Code here then we can help you better.

 private static void ZoomWin(
      Editor ed, Point3d min, Point3d max
    )
    {
      Point2d min2d = new Point2d(min.X, min.Y);
      Point2d max2d = new Point2d(max.X, max.Y);

      ViewTableRecord view =
        new ViewTableRecord();

      view.CenterPoint =
        min2d + ((max2d - min2d) / 2.0);
      view.Height = max2d.Y - min2d.Y;
      view.Width = max2d.X - min2d.X;
      ed.SetCurrentView(view);
    }

 

Message 4 of 18
Hallex
in reply to: autodeskprogrammer

You wrote

>>I am not sure but maybe it can help you

Do you know who is DiningPhilosopher?

LOL

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 5 of 18
autodeskprogrammer
in reply to: Hallex

No I don't know who is he? 

Message 6 of 18


@autodeskprogrammer wrote:

No I don't know who is he? 


Then read: http://forums.autodesk.com/t5/NET/What-happens-with-Tony-Tanzillo/td-p/2800448

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 7 of 18
sfinch1
in reply to: DiningPhilosopher

Sorry for the delay in responding.  I was travelling and just got back.  Thanks for the replies.

 

I was trying to be concise by not posting pages of code, but I know I could have done a better job of explaining.  First, I should mention that I am using AutoCAD Map 3D and there is an FDO data layer involved, BUT I don't believe that has anything to do with the issue I'm facing.  (Maybe I'm wrong, though...)

 

I'm trying to Zoom to a specific X,Y point - either at the same scale or at a specific zoom scale.  I was originally using the Zoom code in the documentation called "Manipulate the Current View" here:

http://docs.autodesk.com/ACD/2013/DEU/index.html?url=files/GUID-FAC1A5EB-2D9E-497B-8FD9-E11D2FF87B93...

No matter what I tried, the Zooms would take me out in space somewhere.  I tried a lot of different things,but never could get it to Zoom to the right place.  Apparently, the transformations don't take into account the Map 3D coordinate system assigned.

 

I then discovered the Map API call AcMapMap.ZoomToExtent() using an MgEnvelope object.  This works correctly for me using this code:

    Public Shared Sub ZoomMapCenter(ZoomCenterPoint As Point3d, ObjectHeight As Double)
        'zoom to a specific point on the map at a reasonable zoom scale to view object

        Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor


        ZoomCenterPoint.TransformBy(ed.CurrentUserCoordinateSystem)

        Dim map As AcMapMap = AcMapMap.GetCurrentMap()
        Dim mapExtent As MgEnvelope = map.GetMapExtent()

        'There is some FDO feature source connected
        If Not mapExtent.IsNull() Then

            Dim centerX As Double = ZoomCenterPoint.X
            Dim centerY As Double = ZoomCenterPoint.Y

            'ed.WriteMessage("center:" & centerX.ToString() & "," & centerY.ToString() & vbLf)

            Dim newExtent As New MgEnvelope(ZoomCenterPoint.X - (ObjectHeight * 3.0), ZoomCenterPoint.Y - (ObjectHeight * 2.0), ZoomCenterPoint.X + (ObjectHeight * 3.0), ZoomCenterPoint.Y + (ObjectHeight * 2.0))

            map.ZoomToExtent(newExtent)

        Else
            'no FDO data source, use AutoCAD API

            Using Tx As Transaction = db.TransactionManager.StartTransaction()
                ed.UpdateTiledViewportsInDatabase()

                Dim viewportTableRec As ViewportTableRecord = TryCast(Tx.GetObject(ed.ActiveViewportId, OpenMode.ForWrite), ViewportTableRecord)

                viewportTableRec.CenterPoint = New Point2d(ZoomCenterPoint.X, ZoomCenterPoint.Y)


                ed.UpdateTiledViewportsFromDatabase()

                Tx.Commit()

            End Using

        End If

    End Sub

 

 

Again, everything works just fine and I'm getting the results I need, except for the fact that the view does not change until the user closes the modal dialog.  The zoom then occurs as expected and recenters the map on the correct location.  I just need for the Zoom to occur when the user clicks the button.

 

The button calling this function is on a modal form which is launched from a paletteset.  At the moment, I am trying by placing the ZoomMapCenter method above in my command class, calling it asynchronously using SendStringToExecute as shown below:

    Private Sub btnZoomTo_Click(sender As System.Object, e As System.EventArgs) Handles btnZoomTo.Click
        'zoom to the correct coordinates

        Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim ed As Editor = doc.Editor

        'zoom to the point based on the selected InventoryID

        If Not CurrentPoint.Equals(New Point3d()) = True Then

            Using edUsrInt As EditorUserInteraction = ed.StartUserInteraction(Me.Handle)


                'zoom to the point
                Dim centerPoint As String = CurrentPoint.X.ToString + "," + CurrentPoint.Y.ToString
                Dim stringToExecute As String = "ZoomToPlant " + centerPoint + " " + CurrentPlantBlockScale.ToString() + " "

                doc.SendStringToExecute(stringToExecute, True, False, False)

                edUsrInt.End()
                Me.Focus()

            End Using

        End If

    End Sub

 I also tried it without using the ed.StartUserInteraction() with no success.

 

Again, everything works just fine except that the view doesn't change until the user closes the modal form.  I'm sure the problem is related to me not fully understanding the session/document context that I'm running under.

 

Thanks for your help.

 

Message 8 of 18
norman.yuan
in reply to: sfinch1

Try call Editor.Regen() at the end of your ZoomMapCenter() method.

Message 9 of 18
Alexander.Rivilis
in reply to: sfinch1

Do you try to use Document.SendStringToExecute from button handler of modal dialog? Document.SendStringToExecute is executed asynchronously. That is why execution will be done only after command is ended. Try to call one of ZoomXXX function from this topic: http://forums.autodesk.com/t5/NET/ZoomWindow-and-ZoomScale/m-p/3249340#M26321

Also can be useful:

http://adndevblog.typepad.com/autocad/2012/04/synchronously-send-and-wait-for-commands-in-autocad-us...

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 10 of 18

but I implemented your code and it worked perfectly - only I disabled some part of your code 

 Public Shared Sub ZoomMapCenter(ZoomCenterPoint As Point3d, ObjectHeight As Double)
        'zoom to a specific point on the map at a reasonable zoom scale to view object

        Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor


        ZoomCenterPoint.TransformBy(ed.CurrentUserCoordinateSystem)

        'Dim map As AcMapMap = Nothing
        'AcMapMap.GetCurrentMap()
        'Dim mapExtent As MgEnvelope = Nothing
        'map.GetMapExtent()

        'There is some FDO feature source connected
        If False Then

            'Dim centerX As Double = ZoomCenterPoint.X
            'Dim centerY As Double = ZoomCenterPoint.Y

            ''ed.WriteMessage("center:" & centerX.ToString() & "," & centerY.ToString() & vbLf)

            'Dim newExtent As New MgEnvelope(ZoomCenterPoint.X - (ObjectHeight * 3.0), ZoomCenterPoint.Y - (ObjectHeight * 2.0), ZoomCenterPoint.X + (ObjectHeight * 3.0), ZoomCenterPoint.Y + (ObjectHeight * 2.0))

            'map.ZoomToExtent(newExtent)

        Else
            'no FDO data source, use AutoCAD API

            Using Tx As Transaction = db.TransactionManager.StartTransaction()
                ed.UpdateTiledViewportsInDatabase()

                Dim viewportTableRec As ViewportTableRecord = TryCast(Tx.GetObject(ed.ActiveViewportId, OpenMode.ForWrite), ViewportTableRecord)

                viewportTableRec.CenterPoint = New Point2d(ZoomCenterPoint.X, ZoomCenterPoint.Y)


                ed.UpdateTiledViewportsFromDatabase()

                Tx.Commit()

            End Using

        End If

    End Sub

 

Message 11 of 18


@autodeskprogrammer wrote:

but I implemented your code and it worked perfectly - only I disabled some part of your code 

<snip>

 


You didn't implement his code in the Click handler of a button on a modal dialog launched from a PaletteSet, because if you had, you would have needed to lock the document before modifying it.

 

The problem is not his code, it is the context in which it runs.

Message 12 of 18

your right,
I implemented all the parts except palette but with palette and dock lock it works perfect

 

I agree "The problem is not his code, it is the context in which it runs."

Message 13 of 18
sfinch1
in reply to: DiningPhilosopher

Still having no luck getting the Zoom to work immediately when the user clicks the button on a modal dialog.

 

I tested the code from a button's click handler on a modeless dialog and it worked immediately as desired.  I then tested it from a button click event on a paletteset and it also zoomed immediately.

 

The modal dialog is launched from the paletteset.  I tried passing a ByRef reference to the calling paletteset as a parameter to the New() method of the modal dialog, and having the modal dialog click handler execute the code on the parent paletteset.  No luck.  The zoom still occurs only after the modal dialog is closed.

 

I also tried launching the modal dialog by using SendStringToExecute() to call a CommandMethod which launches the modal dialog.  Same result.

 

Here's my Zoom function (which works fine for me):

    Public Sub ZoomMapCenter(ZoomCenterPoint As Point3d, ObjectHeight As Double)
        'zoom to a specific point on the map at a reasonable zoom scale to view object

        Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim db As Autodesk.AutoCAD.DatabaseServices.Database = doc.Database
        Dim ed As Editor = doc.Editor


        ZoomCenterPoint.TransformBy(ed.CurrentUserCoordinateSystem)

        Dim map As AcMapMap = AcMapMap.GetCurrentMap()
        Dim mapExtent As MgEnvelope = map.GetMapExtent()

        'There is some FDO feature source connected
        If Not mapExtent.IsNull() Then

            'set a reasonable zoom extent based on the object height passed to this method
            Dim newExtent As New MgEnvelope(ZoomCenterPoint.X - (ObjectHeight * 3.0), ZoomCenterPoint.Y - (ObjectHeight * 2.0), ZoomCenterPoint.X + (ObjectHeight * 3.0), ZoomCenterPoint.Y + (ObjectHeight * 2.0))

            Using acLckDoc As DocumentLock = doc.LockDocument()
                doc.LockDocument()

                map.ZoomToExtent(newExtent)

                AcMapMap.ForceScreenRefresh()

            End Using

        End If
    End Sub

 

I just need to get the above method to execute immediately when called from a modal dialog somehow.  Is there any way that I can do that?

 

Thanks again for all the help.

 

 

Message 14 of 18
_gile
in reply to: sfinch1

Hi,

 

here's a way working for me:

- the 'Test' command shows a Paletteset which contains a UserControl : 'ZoomControl'

- the 'ZoomControl' UserControl contains a button (btnDialog) to open a Form as modal dialog: 'Dialog'

- the 'Dialog' Form contains a button (btnZoom) which does a zoom extents.

 

It seems to me there's no need to call LockDocument() if you open the dialog using Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog() method.

 

The CommandMethods class where the PaletteSet is created

using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;

[assembly: CommandClass(typeof(ZoomFromModalDialogFromPalette.CommandMethods))]

namespace ZoomFromModalDialogFromPalette
{
    public class CommandMethods
    {
        private static PaletteSet ps;

        [CommandMethod("Test", CommandFlags.Modal)]
        public void Test()
        {
            if (ps == null)
            {
                ps = new PaletteSet("zoom", new Guid("{BEE26D4D-DD21-4B01-8080-7B6E38AD3FBA}"));
                ps.Style =
                  PaletteSetStyles.ShowPropertiesMenu |
                  PaletteSetStyles.ShowAutoHideButton |
                  PaletteSetStyles.ShowCloseButton;
                ps.Name = "Test Zoom";
                ps.Add("Zoom", new ZoomControl());
            }
            ps.Visible = true;
        }
    }
}

 

The ZoomControl class with the btnDialog event handler

using System;
using System.Windows.Forms;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace ZoomFromModalDialogFromPalette
{
    public partial class ZoomControl : UserControl
    {
        public ZoomControl()
        {
            InitializeComponent();
        }

        private void btnDialog_Click(object sender, EventArgs e)
        {
            Dialog dlg = new Dialog();
            AcAp.ShowModalDialog(dlg);
        }
    }
}

 

The Dialog class in which the btnZoom event handler is defined

using System;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace ZoomFromModalDialogFromPalette
{
    public partial class Dialog : Form
    {
        public Dialog()
        {
            InitializeComponent();
        }

        private void btnZoom_Click(object sender, EventArgs e)
        {
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            using (ViewTableRecord view = ed.GetCurrentView())
            {
                Matrix3d worldToEye =
                    (Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) *
                    Matrix3d.Displacement(view.Target - Point3d.Origin) *
                    Matrix3d.PlaneToWorld(view.ViewDirection)).Inverse();
                Extents3d ext = (short)AcAp.GetSystemVariable("cvport") == 1 ?
                new Extents3d(db.Pextmin, db.Pextmax) :
                new Extents3d(db.Extmin, db.Extmax);
                ext.TransformBy(worldToEye);
                view.Width = ext.MaxPoint.X - ext.MinPoint.X;
                view.Height = ext.MaxPoint.Y - ext.MinPoint.Y;
                view.CenterPoint = new Point2d(
                    (ext.MaxPoint.X + ext.MinPoint.X) / 2.0,
                    (ext.MaxPoint.Y + ext.MinPoint.Y) / 2.0);
                ed.SetCurrentView(view);
            }
        }
    }
}

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 15 of 18
sfinch1
in reply to: DiningPhilosopher

Gilles,

 

Thanks very much for the code example, but in my particular situation, I have to use the Map 3D AcMapMap.ZoomToExtent() method to get the correct zoom results. 

 

With the Zoom method in the API documentation or your example, the code depends on the extents of the drawing.  With a state plane coordinate system in use in my drawing, the extents are many miles across while the actual bounds of the existing entities are less than 1/2 mile across.  Zooms using those methods take me way out in space somewhere.  I found that the AcMapMap.ZoomToExtent() method works perfectly for me. and solves those issues.

 

I want to test your code, but I'm only slightly familiar with C# and am doing something wrong in getting the project references set up for testing.  What your example shows seems to be pretty much what I'm already doing other than the differences in the zoom methods.

 

Steve

 

Message 16 of 18
DiningPhilosopher
in reply to: sfinch1

I'm not familiar with how the Map API is doing the zoom, but you might want to try setting your Form's Visible property to false, just before you call the API and as soon as it returns, set it to True. And you can for good measure, put a call to Application.DoEvents() right after the call to the MAP API.  Modal dialogs have their own message pump and that seems to be the problem here, so by temporarily hiding and then immediately showing your form, it should cause AutoCAD to process any pending messages.

Message 17 of 18
sfinch1
in reply to: norman.yuan

Thanks, I tried all of the calls below, but still nothing happens until the dialog is closed. AcMapMap.ForceScreenRefresh() ed.Regen() System.Windows.Forms.Application.DoEvents()
Message 18 of 18
quigs
in reply to: sfinch1

Hi,

I use this code and it works Ok for me.  It is called from a button:

 

 

    Dim Insp As Point3d = New Point3d(500, 500, 0)
    Dim AcApp As Autodesk.AutoCAD.Interop.AcadApplication
    AcApp = CType(Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication, Autodesk.AutoCAD.Interop.AcadApplication)
    AcApp.ZoomCenter(Insp.ToArray(), 1000)
    Application.DocumentManager.MdiActiveDocument.Editor.Regen()

 

My name is Martin.. 😄

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost