Communauté
AutoCAD – tous produits - Français
Bienvenue sur les forums AutoCAD d’Autodesk. Partagez vos connaissances, posez des questions, et explorez les sujets AutoCAD populaires.
annuler
Affichage des résultats de 
Afficher  uniquement  | Rechercher plutôt 
Vouliez-vous dire : 

c# problème de zoom

4 RÉPONSES 4
RÉSOLU
Répondre
Message 1 sur 5
Jean-Marc68
765 Visites, 4 Réponses

c# problème de zoom

Salut à toutes et à tous,

 

Dans une application que j'ai développée j'ai un problème de zoom.

 

L'utilisateur doit sélectionner des textes et ceux-ci doivent se mettre dans une table au fur et à mesure de leur saisie.

J'utilise donc un ed.GetSelection(acPSOpts, acFilter); avec un acPSOpts.SingleOnly = true; pour ne saisir qu'un seul point à la fois.

Comme je ne veux pas que l'utilisateur soit obligé de cliquer sur le bouton qui lance la saisie à chaque point (quand il y a 300 points à saisir c'est un peut gênant), j'ai mis la saisie dans un while.

Tant que l'utilisateur n'a pas cliquer sur escape, on relance la saisie d'un nouveau point.

Cela fonctionne bien sauf au niveau du zoom.

On dirait que le view est figé au moment où l'utilisateur clique sur le bouton pour démarrer la saisie.

A chaque saisie de point l'utilisateur pour zoomer, faire un pan etc ..., mais une fois le point saisi il revient automatiquement à l'endroit et au zoom (est-ce un view ou une autre raison ?) qui étaient au moment où l'utilisateur a lancé la méthode.

 

Voici mes codes :

 

Méthode d'entrée (clic bouton):

private void piquerButton_Click(object sender, EventArgs e)
        {
            PointType SaisiePointType = PointType.Point;
            ApplicationAcadCommands.StopAsked = false;

            //Mettre le focus sur le dessin courant
            Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView();

            //Tant que l'utilisateur n'a pas appuyé sur esc
            while (!ApplicationAcadCommands.StopAsked)
            {
                //Sélectionner un point
                TopocomPoint pt = ApplicationAcadCommands.PointSelection(string.Format("\nSélectionnez un numéro de point{0}",SaisiePointType == PointType.Point?"" : " de vérification"));
                //Si un point a été sélectionné
                if (pt != null)
                {
                    //Extraire le point de la base de données
                    DataSetDblVerif.PointsRow drPoint = DatasetDoubleVerification.Points.FindPointByNoPoint(pt.NoPoint);
                    //Si le point n'est pas dans la table des points on l'y ajoute
                    if (drPoint == null)
                    {
                        DataSetDblVerif.PointsRow newPt = DatasetDoubleVerification.Points.NewPointsRow();
                        newPt.NoPoint = pt.NoPoint;
                        newPt.X = pt.X;
                        newPt.Y = pt.Y;
                        newPt.Z = pt.Z;
                        DatasetDoubleVerification.Points.AddPointsRow(newPt);
                    }
                    //Sinon mettre les coordonnées à jour
                    else
                    {
                        drPoint.X = pt.X;
                        drPoint.Y = pt.Y;
                        drPoint.Z = pt.Z;
                    }



                    if (SaisiePointType == PointType.Point)
                    {
                        DataSetDblVerif.PointVsPtVerifRow PointVsPtVerifNewRow = DatasetDoubleVerification.PointVsPtVerif.NewPointVsPtVerifRow();
                        PointVsPtVerifNewRow.NoPoint = pt.NoPoint;
                        SaisiePointType = PointType.Verif;
                        DatasetDoubleVerification.PointVsPtVerif.AddPointVsPtVerifRow(PointVsPtVerifNewRow);
                    }
                    else
                    {
                        DataSetDblVerif.PointVsPtVerifRow PointVsPtVerifLastRow = (DataSetDblVerif.PointVsPtVerifRow)DatasetDoubleVerification.PointVsPtVerif.Rows[DatasetDoubleVerification.PointVsPtVerif.Count - 1];
                        PointVsPtVerifLastRow.NoPtVerif = pt.NoPoint;
                        SaisiePointType = PointType.Point;
                    }
                }
            }
        }

 Fonction appelée de manière récurente dans le while:

static public TopocomPoint PointSelection(string commandLineText)
        {
            TopocomPoint topocomPoint = null;

            //Récupère le document courant, sa base de données, et demarre une transaction
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;

            //Récupération de l'éditeur de la base de données courante
            Editor ed = acDoc.Editor;

            //Démarre une nouvelle transaction
            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                //Création d'un filtre pour récupérer uniquement les textes
                TypedValue[] acFilList = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "TEXT") };
                SelectionFilter acFilter = new SelectionFilter(acFilList);
                PromptSelectionOptions acPSOpts = new PromptSelectionOptions();
                acPSOpts.MessageForAdding = commandLineText;
                acPSOpts.SingleOnly = true;

                //Sélection des textes
                PromptSelectionResult acPSResPoint = ed.GetSelection(acPSOpts, acFilter);

                //Si la sélection a réussi
                if (acPSResPoint.Status == PromptStatus.OK)
                {
                    SelectionSet acSSetPoint = acPSResPoint.Value;
                    ObjectId[] acIdsPoint = acSSetPoint.GetObjectIds();
                    for (int i = 0; i < acIdsPoint.Length; i++)
                    {
                        //Récupération de l'objet texte saisi
                        DBText acTextPoint = (DBText)acTrans.GetObject(acIdsPoint[i], OpenMode.ForRead);
                        //Récupération des données du Texte saisi
                        Point3d textPoint = acTextPoint.Position;
                        topocomPoint = new TopocomPoint(acTextPoint.TextString.TrimStart(), 0, textPoint.X, textPoint.Y, textPoint.Z);
                    }
                }
                else if (acPSResPoint.Status == PromptStatus.Cancel)
                {
                    //Revenir à une nouvelle ligne de commande
                    Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();
                    StopAsked = true;
                }
            }
            return topocomPoint;
        }

 

Comment faire pour que le zoom et le pan (ou le view si c'est le cas) ne se réinitialise pas à chaque saisie de point ?

 

Merci de vos z'avis z'avisés,

JM

4 RÉPONSES 4
Message 2 sur 5
_gile
en réponse à: Jean-Marc68

Salut,

 

Je pense que le problème vient du fait que que tu ne réalises (Commit) pas la transaction à l'intérieur de laquelle tu invites l'utilisateur à sélectionner un texte, ce qui revient à une annulation (Undo) de ce qui a été fait pendant la transaction (y compris les zooms et pans faits par l'utilisateur).

 

Mais il me semble qu'il est possible d'implémenter une sélection multiple de manière plus simple (et plus performante) à l'intérieur d'une unique transaction.

Personnellement, je placerais cette invite dans 'piquerButton_Click' et j'appellerais une méthode pour traiter le texte sélectionné depuis celle-ci. La méthode appelée pourrais retourner un Booléen qui permettrait de définir le prochain message d'invite.

 

        private void piquerButton_Click(object sender, EventArgs e)
        {
            bool retourMethode = false;
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptSelectionOptions options = new PromptSelectionOptions();
            options.SingleOnly = true;
            SelectionFilter filter = new SelectionFilter(new TypedValue[] { new TypedValue(0, "TEXT") });
            PromptSelectionResult psr;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                while (true)
                {
                    psr = ed.GetSelection(options, filter);
                    if (psr.Status != PromptStatus.OK) break;
                    DBText text = (DBText)tr.GetObject(psr.Value.GetObjectIds()[0], OpenMode.ForRead);
                    // appeler ici une méthode qui traite le texte sélectionné et retourne un Booléen
                    options.MessageForAdding =
                        string.Format("\nSélectionnez un numéro de point {0}", retourMethode ? "" : "de vérification");
                }
                tr.Commit();
            }
        }

 

Dans la mesure où le filtre de sélection ne concerne que le type d'entité, on peut très bien utiliser GetEntity() plutôt que GetSelection()

 

        private void piquerButton_Click(object sender, EventArgs e)
        {
            bool retourMethode = false;
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptEntityOptions peo = new PromptEntityOptions("\nSélectionnez un numéro de point: ");
            peo.SetRejectMessage("Objet non valide.");
            peo.AddAllowedClass(typeof(DBText), true);
            PromptEntityResult per;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                while (true)
                {
                    per = ed.GetEntity(peo);
                    if (per.Status != PromptStatus.OK) break;
                    DBText text = (DBText)tr.GetObject(per.ObjectId, OpenMode.ForRead);
                    // appeler ici une méthode qui traite le texte sélectionné et retourne un Booléen
                    peo.Message =
                        string.Format("\nSélectionnez un numéro de point {0}", retourMethode ? "" : "de vérification");
                }
                tr.Commit();
            }
        }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 sur 5
Jean-Marc68
en réponse à: _gile

Arf, ben oui, évidemment. Le Commit.

Je cherchais beaucoup trop loin, et comme aucune modif n'est apportée à la db du document, je pensais qu'il n'était pas nécessaire, mais en effet les zoom y sont intégrés.

 

Merci beaucoup de ton aide _gile.

Message 4 sur 5
_gile
en réponse à: Jean-Marc68

Salut,

 

D'après ce que j'ai pu lire, même si aucune modification n'est intervenue dans une transaction, il est plus avantageux de réaliser celle-ci (Commit).

Ne pas le faire est équivalent à appeler Abort() ce qui entraine une annulation (rollback) qui est toujours plus couteuse.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 sur 5
Jean-Marc68
en réponse à: _gile

Bon à savoir aussi.

 

Merci Gilles

Vous n'avez pas trouvé ce que vous recherchiez ? Posez une question à la communauté ou partagez vos connaissances.

Publier dans les forums  

Autodesk Design & Make Report