AutoCAD - Francais

AutoCAD - Francais

Répondre
Valued Contributor
Jean-Marc68
Envois : 94
Inscrit : ‎01-03-2007
Message 1 sur 5 (335 visites)
Solution approuvée

c# problème de zoom

335 Visites, 4 Réponses
12-13-2012 08:44 AM

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

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();
}
}

 

*Expert Elite*
_gile
Envois : 2 114
Inscrit : ‎04-29-2006
Message 2 sur 5 (314 visites)

Re : c# problème de zoom

12-16-2012 01:46 AM 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
Valued Contributor
Jean-Marc68
Envois : 94
Inscrit : ‎01-03-2007
Message 3 sur 5 (297 visites)

Re : c# problème de zoom

12-17-2012 05:23 AM 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.

*Expert Elite*
_gile
Envois : 2 114
Inscrit : ‎04-29-2006
Message 4 sur 5 (285 visites)

Re : c# problème de zoom

12-18-2012 12:30 AM 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
Valued Contributor
Jean-Marc68
Envois : 94
Inscrit : ‎01-03-2007
Message 5 sur 5 (274 visites)

Re : c# problème de zoom

12-19-2012 01:44 PM en réponse à : _gile

Bon à savoir aussi.

 

Merci Gilles

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Annonces
Are You Going To Be @ AU 2014? Feel free to drop by our AU topic post and share your plans, plug a class that you're teaching, or simply check out who else from the community might be in attendance. Ohh and don't forgot to stop by the Autodesk Help | Learn | Collaborate booths in the Exhibit Hall and meet our community team if you get a chance!