Aller au contenu

dégèle d'un calque


Messages recommandés

Bonjour

 

J'ai une fonction pour geler ou dégeler un calque. Le problème est que lors du dégèle les Entity qui sont dans ce calque n'apparraissent pas à l'écran.

 

Savez vous comment faire ?

 

Voici mes fonctions :

       public static void GelerCalque(string nom, bool geler)
       {
           if (transaction == null)
           {
               throw new ExceptionTransactionAutocadInvalide("Transaction non créée");
           }
           if (ExisteCalque(nom))
           {
               if (getCalque(nom) == database.Clayer) SetCalqueCourant("0");
               LayerTableRecord ltr = (LayerTableRecord)transaction.GetObject(getCalque(nom), OpenMode.ForWrite);
               ltr.IsFrozen = geler;
           }
       }

       public static bool ExisteCalque(string nom)
       {
           if (transaction == null)
           {
               throw new ExceptionTransactionAutocadInvalide("Transaction non créée");
           }
           return layerTable.Has(nom);
       }

       private static ObjectId getCalque(string nom)
       {
           if (transaction == null)
           {
               throw new ExceptionTransactionAutocadInvalide("Transaction non créée");
           }
           if (!ExisteCalque(nom))
           {
               throw new ExceptionCalque("Le calque " + nom + " n'existe pas");
           }
           return layerTable[nom];
       }


 

Merci d'avance de vos réponses.

Lien vers le commentaire
Partager sur d’autres sites

j'ai mis un Regen mais ça ne marche pas au clic que le bouton, il faut deux clic que le bouton pour que les Entity s'affiche.

 

  private void RadioButton_Checked_2(object sender, RoutedEventArgs e)
       {
          
           MonAutocad.NouvelleTransaction();
           MonAutocad.GelerCalque(new Regex("^" + CONSTANTES.VUE.CALQUE_ABC + "i?n[\\dt]"), true);
           MonAutocad.GelerCalque(CONSTANTES.VUE.CALQUE_ABC + "n" + niveau, false);
           MonAutocad.SetCalqueCourant(CONSTANTES.VUE.CALQUE_ABC + "n" + niveau);
           MonAutocad.Commit();
       }

//J'ai mis le regen ici :

public static void SetCalqueCourant(string nom)
       {
           if (transaction == null)
           {
               throw new ExceptionTransactionAutocadInvalide("Transaction non créée");
           }
           if (getCalque(nom) == database.Clayer) return;
           GelerCalque(nom, false);
           CacherCalque(nom, false);
           VerrouillerCalque(nom, false);
           database.Clayer = getCalque(nom);
           editor.Regen();
       }

 

CacherCalque et VerouillerCalque sont comme GelerCalque (juste une propriété qui change)

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

C'est très difficile de t'aider au vu du nombre de sous routines que tu appelles et dont tu ne fournis pas toujours le code.

 

À mon avis, comme je te l'ai déjà dit par ailleurs, tu compliques vraiment inutilement des choses fort simples :

 

La méthode GelerCalque() appelle ExisteCalque(), puis getCalque() qui appelle aussi ExisteCalque() tout ça pour tester l’existence d'un calque dans la table des calque (avec une variable layerTable dont on ne sait pas où elle a été initialisé) et retourner son ObjectId...

 

À trop 'factoriser' le code, on finit par le rendre moins lisible (surtout pour ceux qui ne l'ont pas écrit).

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Les méthodes sont toutes indépendantes les une des autres d'où parfois une redondance dans les tests.

 

Il est lisible dans le sens qu'il suffit de "lire" le code d'une fonction pour comprendre, sans forcément aller voir le contenu des sous fonctions :)

 

la layerTable est bien initialisé, je n'ai aucun problème avec juste comme je disais le dégèle des calques sui n'affiche pas les Entity sur le calque. (Les Entity sont bien sur le calque, quand je le fait à la main via l'IHM d'Autocad je n'ai pas de problème).

Lien vers le commentaire
Partager sur d’autres sites

Il est lisible dans le sens qu'il suffit de "lire" le code d'une fonction pour comprendre, sans forcément aller voir le contenu des sous fonctions :)

 

Sauf que, quand tu demandes de l'aide comme ici, on est bien obligé d'aller lire le code des sous-fonctions.

 

Pour ton problème, je pencherai pour une question de contexte.

Tu sembles appeler ces fonctions depuis une boite de dialogue, est-elle modale ou non ?

Dans le second cas comment et où est passé le focus à l'éditeur AutoCAD ?

As-tu essayé d'appeler les mêmes fonctions depuis une simple commande AutoCAD (CommandMethod) ?

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Oui et encore merci de l'aide :)

 

pas de boite de dialogue mais il est vrai que je les appel depuis un event d'une palette crée avec WPF.

 

Pour le focus il y a un autofocus à false sur mon PaletSet : _ps.KeepFocus = false;

 

Je ne vois pas ce que tu veux dire pour la "simple commande AutoCAD" :/

 

Le problème est que lorsque je fais le regen ça m'affiche bien les informations mais quand mon curseur retourne sur l'écran d'autocad tout disparaît comme si je n'avais pas fait le regen.

Modifié par bathepn
Lien vers le commentaire
Partager sur d’autres sites

pas de boite de dialogue mais il est vrai que je les appel depuis un event d'une palette crée avec WPF.

Une palette est avant tout un boite de dialogue non modale (modeless), qui est, en plus, ancrable et repliable.

Avec les boites de dialogue non modales, le focus ne bascule pas toujours automatiquement de la boite de dialogue à la fenêtre AutoCAD quand le curseur passe de l'un à l'autre.

 

Je ne vois pas ce que tu veux dire pour la "simple commande AutoCAD" :/

Pour tester, tu définis une commande AutoCAD (avec l'attribut CommandMethod) qui contient le même code que dans ton gestionnaire d'évènement. tu pourras ainsi tester plus facilement le comportement de ton code et les différences éventuelles avec le fait de l'appeler depuis une boite non modale.

Il peut aussi être intéressant d'appeler des commandes ainsi définies depuis les gestionnaires d'évènement pour laisser le soin à AutoCAD de gérer certaines choses comme le verrouillage du document (cette pratique est recommandée par Autodesk).

 

Le problème est que lorsque je fais le regen ça m'affiche bien les informations mais quand mon curseur retourne sur l'écran d'autocad tout disparaît comme si je n'avais pas fait le regen.

As-tu essayé de faire le regen après que la transaction soit terminée (Commit() et Dispose() ou fin de l'instruction using) ?

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Je crois que mes transactions je les termine pas comme il faut.

 

public static void Commit()
       {
           if (transaction == null)
           {
               throw new ExceptionTransactionAutocadInvalide("Transaction non créée");

           }
           transaction.Commit();
           transaction = null;
           document = null;
       }

 

Je ne fais jamais de dispose c'est peut-être pas normal.

 

 

Mais c'est vraiment bizarre car si j'execute deux fois de suite le code pour geler mes calques ça marche alors que pourtant j'ai vérifié il passe dans les même tests et les même instructions.

 

http://9gag.com/gag/anYZ9Eo/my-code-works-but-i-don-t-know-why

Lien vers le commentaire
Partager sur d’autres sites

J'ai trouvé !!!!

 

L'idée du regen était bonne mais ne marchait pas avec moi, j'ai utiliser une autre méthode.

 

une fois le dégèle des calque je fais ça :

 

document.SendStringToExecute("_REGENALL ", true, false, false);

 

et ça m'affiche ce qu'il faut :)

Lien vers le commentaire
Partager sur d’autres sites

Voilà ce que j'appelle une méthode simple et clairement lisible qui peut aussi bien être appelée depuis une simple commande, une boite de dialogue modale ou une palette.

 

        public static void SetCurrentLayer(string layerName)
       {
           Document doc = Application.DocumentManager.MdiActiveDocument;
           Database db = doc.Database;
           Editor ed = doc.Editor;

           using (doc.LockDocument())
           using (Transaction tr = db.TransactionManager.StartTransaction())
           {
               LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
               if (!lt.Has(layerName))
                   return;

               LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(lt[layerName], OpenMode.ForWrite);
               ltr.IsFrozen = false;
               ltr.IsHidden = false;
               ltr.IsLocked = false;
               db.Clayer = ltr.ObjectId;

               tr.Commit(); // validation des changements effectués
           } // fin de using : libère les ressources de la transaction et déverrouille le document
           ed.Regen();
       }

 

On voit clairement que toutes les instructions concernant la table des calques et le calque à rendre courant sont lancée depuis le bloc de code de l'instruction using qui ouvre la transaction. Ce bloc using garanti que Dispose() sera appelé pour la transaction ainsi que pour tous les objets ouverts avec la transaction (lt et ltr), que le document sera déverrouillé.

Et que la régénération n'intervient qu'une fois que les changements sont validés.

 

Si tu préfères compliquer les choses en remplaçant chaque instruction par un appel à une sous-fonction, libre à toi, mais tu dois absolument respecter l'architecture du code ci-dessus.

Par ailleurs, remplacer ces instructions par des appels à des fonctions ne fait pas que compliquer les choses (à mon avis) mais rend certainement le code moins efficient en terme de performances, ne serait-ce qu'à cause du test systématique d'existence de la transaction.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité