Jolie bibliothèque, je ne connaissais pas smile
avatarAll right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)
Zeph -> ok. Donc si on veut écrire de manière dégueulasse, on peut. grin
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Bon, continuation avec des progrès dans la conception des forms, mais c'est pas encore tout à fait ça. Donc un screen : tromb Fichier joint : 8HZj

Schéma 1 :
Y a-t-il une gestion de la taille minimale des éléments ? En l'occurence, si je réduis la GroupBox "Name decoration", mes éléments de NumericUpDown et de TextBox vont se réduire et disparaitre.
L'éditeur est-il capable de calculer automatiquement une taille minimale pour ces éléments ?
L'éditeur est-il capable d'utiliser ce minimum pour empêcher la réduction de la GroupBox ?

Schéma 2 :
Même question quant à une taille minimum en hauteur, sauf que cette fois mes éléments ne sont même pas stretchés, ils sont tout simplement tronqués

Schéma 3 :
Je peux agrandir ma GroupBox autant que je veux horizontalement, et les champs d'input vont augmenter en taille pour remplir tout l'espace qui leur est laissé. Ca, ça me va.
Par contre, je n'arrive pas à fixer la taille de ma GroupBox de manière automatique en hauteur, de manière à ce que les 4 lignes appaissent en hauteur, et que l'espacement entre ces lignes grandisse si j'étire ma Groupbox en hauteur. Quelle méthode employer pour y parvenir ?

Pour info, j'arrive à faire tout ça avec Qt, mais là je sèche, merci pour votre aide. smile
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Bon j'arrive un peu tard sur le topic, mais… grin

1)
Non, il n'y a pas de taille minimum des éléments (si y'a pas la place de les mettre, je vois pas ce que tu peux y faire), mais tu peux mettre une taille minimale à ta fenêtre si tu détermines qu'en dessous d'une certaine taille, ça ne tient pas comme il faut. Si c'est une boîte de dialogue, une pratique courante est de fixer complètement la taille de la fenêtre quand celle-ci s'y prête. (ex: tient facilement entièrement dans l'écran)
Les guidelines sur les boîtes de dialogue sont ici: https://msdn.microsoft.com/en-us/library/windows/desktop/dn742499(v=vs.85).aspx
Plus généralement, sur les fenêtres: https://msdn.microsoft.com/en-us/library/windows/desktop/dn742489(v=vs.85).aspx
Et carrément l'index: https://msdn.microsoft.com/en-us/library/windows/desktop/dn688964(v=vs.85).aspx grin

2)
De mémoire, tu ne peux pas.
Normalement tu n'as tout bonnement pas besoin d'une fonctionnalité de taille minimale pour la hauteur, puisque le contenu de ton GroupBox ne devrait pas être amené à changer, et une hauteur fixe sera alors tout à fait appropriée.
Par contre, si ma mémoire est bonne, c'est un peu chiant de trouver la hauteur parfaite, car l'éditeur Windows Forms ne t'affiche pas les guides de taille idéale pour le redimensionnement d'un GroupBox. Ma technique personnelle dans ce cas c'est de bouger légèrement l'élément le plus bas pour voir combien de place il reste pour que l'alignement soit parfait, puis ajuster jusqu'à ce que ce soit bon. cheeky

3)
C'est totalement non standard de changer l'espacement des éléments d'un GroupBox au redimensionnement, et probablement grandement perturbant pour l'utilisateur.
Même si c'est possible de le faire (par ex. manuellement en réagissant aux évènements), je te le déconseille fortement tongue


En gros, si je résumais, pour une fenêtre type boîte de dialogue ou assimilé, l'idée, c'est que ton interface est par défaut bien fichue:
  • Ta fenêtre a la bonne taille. (Pas trop grande pour que ça tienne sur le plus petit écran que tu veux supporter, pas trop petite, afin que le maximum de contenu reste visible et manipulable)
  • Ta fenêtre a une taille minimale imposée pour empêcher que son contenu devienne inutilisable.
  • Tes éléments graphiques restent autant que possible au même endroit.
  • La taille horizontale des champs peut/doit varier en fonction de l'espace disponible, si tu choisis un layout à taille variable.
  • La taille verticale des éléments ne change pas, hors quelques exceptions (ex: conteneur principal de la fenêtre)
  • Les éléments de la fenêtre ne se déplacent pas bizarrement d'un endroit à un autre pendant ou après un redimensionnement.
  • Si tu as trop d'éléments à afficher d'un coup et que d'autres alternatives de présentation (TabControl) ne semblent pas appropriées, envisage l'utilisation d'une barre de défilement verticale).

C'est sûr que le moteur de layout de Windows Forms reste plutôt limité, mais il est tout à fait apte à produire des interfaces standards (type dialogues de propriétés de Windows) et même un peu mieux que ce qui se fait par défaut.
Pour le reste, tu peux faire beaucoup de choses en gérant les événements toi même (repositionner les éléments toi-même pendant/après un redimensionnement), et ça se justifie parfaitement dans certains cas.
avatarLe scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
Ok, ben un grand merci pour ces explications détaillées top

C'est un peu ce que je "craignais", devoir décider d'une taille de fenêtre, d'éléments divers et variés, et de faire du positionnement au pixel près à la main (on est en 2016, Qt se démerde très bien de tout ça, en fonction du thème courant, bref ; et tout ne pètera pas avec un thème pour déficients visuels et des très grandes polices. Avec GDI+, faut croire que si).

Mais ça veut dire que de mon côté :
- faut que je lise les guidelines de la plateforme, au moins dans les grandes lignes bien sûr ^^
- faut que je change mon approche pour être plus "directif" dans ma façon de composer une interface. Ca va être coton, je suis nul grin

Mais merci encore ! smile
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Hmm, normalement, Windows Forms gère "correctement" la mise à l'échelle. C'est un peu horrible pour certains composants (ToolStrip & co.) qui ne sont pas réellement natifs, mais pour le reste ça se fait plutôt bien. (On verra en temps voulu pour les détails)

À la base, le designer Windows Forms était basé sur une grille, mais depuis une éternité maintenant, tu as les SnapLines qui te permettent de positionner correctement les éléments sans avoir à te soucier de leur taille ou position exacte. Du coup c'est au pixel près oui, mais tu n'a que rarement à regarder le positionnement au pixel de tes éléments grin

PS: Sinon tu as toujours WPF mais c'est carrément une autre paire de manches. (Un tas de trucs qui étaient compliqués avec Windows Forms deviennent très simples, et réciproquement grin)

Et non, lire les guidelines n'est pas une obligation (je ne les ai jamais lues en entier, perso) mais ça peut te guider dans certains cas un peu complexes. Pour le reste, s'inspirer de ce que fournit nativement le système d'exploitation est souvent une bonne façon de procéder. (OK, avec Windows 10, ça devient difficile…)
De manière générale, c'est assez difficile d'arbitrer les choix d'UI. Quand tu peux, c'est bien de coller à l'usage, mais parfois l'usage semble un peu pourri dans ton cas particulier, et là il faut chercher l'inspiration ailleurs, voire créer un truc toi-même; et dans ce cas, c'est difficile de déterminer objectivement ce que vaut ton truc par rapport au reste.
avatarLe scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
GoldenCrystal (./95) :
PS: Sinon tu as toujours WPF mais c'est carrément une autre paire de manches. (Un tas de trucs qui étaient compliqués avec Windows Forms deviennent très simples, et réciproquement grin)

pencil
Ok, merci beaucoup. Je te suis tout à fait quant à la difficulté de juger de ce qu'on fait. J'ai tendance à trouver ce que je fais ou très nul (parce que ça l'est), ou très bien (mais tout le monde dit que c'est très nul grin). Je pense que je serai toujours fâché avec les ui, mais j'en prends mon parti, en essayant de faire au plus simple.
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
GoldenCrystal (./93) :
Non, il n'y a pas de taille minimum des éléments (si y'a pas la place de les mettre, je vois pas ce que tu peux y faire)
La taille minimum dans Qt dont parle Folco est remontée le long de la hiérarchie: le layout conteneur calcule sa taille minimale en fonction de celle de ce qu'il contient, et le conteneur du layout reprend la taille minimale du layout, tout cela récursivement si nécessaire. Du coup, ça te donne une taille minimale de la fenêtre automatiquement calculée.
GoldenCrystal (./95) :
PS: Sinon tu as toujours WPF mais c'est carrément une autre paire de manches. (Un tas de trucs qui étaient compliqués avec Windows Forms deviennent très simples, et réciproquement grin)
Sinon, tu as aussi https://gitlab.com/ddobrev/QtSharp. smile
avatarMes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité
Ah, question que je me pose, même si je pense avoir la réponse désormais : les contrôles d'un form possèdent les données qu'ils affichent ?
Par exemple, une textbox semble posséder le texte qu'elle affiche, et non une référence vers un texte existant ailleurs en mémoire.

C'est chiant, parce que ça rend difficile le découplage entre ui et données. Si seules des références étaient possédées par les contrôles, les données pourraient être dans des classes de données pensées comme telles.

D'ailleurs, aucune lib n'aborde les choses sous cet angle ? Et comment vous-y prenez-vous pour séparer proprement ui et données avec un framework de ce genre (ou Qt : même combat) ?
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
De manière générale, le texte est toujours "possédé" par les contrôles, pour des raisons de simplicité.
Par contre tu peux utiliser les fonctionnalités de Data Binding pour relier une propriété d'un contrôle avec une valeur qui se trouve dans un autre objet.
Par exemple, Windows Forms propose très facilement de relier une propriété avec une valeur de Setting. (Tu peux définir tes settings dans la page propriétés du projet ou en cliquant sur le fichier Settings dans le dossier "Properties" du projet)
Pour tous les autres modes, il va te falloir un objet qui te serve de "DataSource".
Il y a plusieurs façons de faire, mais ça fait partie des trucs qui étaient assez peu souples avec Windows Forms. Tu pouvais utiliser un DataSet fortement typé (Qui représente plus ou moins un bout d'une base de données), ou bien des objets, mais je ne me souviens plus très bien de cette partie.
De manière générale, tu dois créer des objets qui implementent l'interface INotifyPropertyChanged. Cela permet de communiquer entre l'objet et le contrôle qui s'y attache.

Si tu fais du WPF, le "pattern" MVVM propose de séparer l'interface entre un objet qui représente l'interface de manière abstraite (il possède un état et toutes les méthodes permettant de mettre à jour son état nécessaires à l'interface, mais aucune référence à une implémentation de fenêtre, de contrôle ou un truc du genre) et ta classe d'interface concrète, qui ne contiendra que du code directement lié à l'interface, voire vraiment pas grand chose si tu ajoutes certains frameworks à ton projet. Après, c'est dans la déclaration de l'interface que tu déclares quel contrôle utilise quel champ de l'objet.

Quoi qu'il en soit tu devrais trouver de la documentation sur le Data Binding Windows Forms dans MSDN, mais c'est assez velu ^^
avatarLe scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
Héhé, j'entrevois ce dont tu parles dans l'interface : tromb Fichier joint : x7Bx
Je vais chercher de ce côté, ainsi que de l'interface INotifyPropertyChanged.
Si c'est bien pensé, c'est le genre de chose qui pourrait me changer la vie top
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Je dirais que c'était bien pensé à l'époque où ça avait été créé, mais qu'aujourd'hui on fait mieux… grin
(Rien que d'avoir des fichiers xml qui trainent partout pour définir tes DataSource, c'est vraiment moisi, mais bon ^^)

Sinon pour approfondir sur INotifyPropertyChanged, je te propose une classe de base pour implémenter tes objets de Data Binding: https://github.com/GoldenCrystal/NetUnicodeInfo/blob/master/UnicodeCharacterInspector/BindableObject.cs .
C'est plus ou moins le genre de classe que beaucoup de monde utilise pour ça, car ça t'évite de réinventer la roue dans chacun de tes objets. (Et y'a pas 50 façons de faire ça ^^)

Avec ça, tu peux implémenter tes propriétés de cette façon:
public class Person : BindableObject
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set { SetValue(ref _name, value); }
    }
}

J'imagine que tu as déjà trouvé la page, mais je met quand même un lien vers l'index de la doc sur le Data Binding pour Windows Forms: https://msdn.microsoft.com/en-us/library/ef2xyb33(v=vs.110).aspx
La plupart des trucs importants y sont expliqués, mais il faut fouiller un peu wink
avatarLe scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
Yup merci, j'ai passé un petit moment dedans. On peut aller très loin apparemment, c'est parfait. smile
Et merci pour ta classe, je vais regarder. smile

Par contre, je me prends la tête depuis une heure sur une connerie pas possible (oui, ça m'a pourri la soirée couic) :
J'ai écrit ça : private void NotifyPropertyChanged([CallerMemberName] string propertyName = null) après avoir consciencieusement écrit using System.Runtime.CompilerServices;, comme c'est documenté ici.
Mais il ne veut pas de mon CallerMemberName, le même que je retrouve dans ta classe ! Il me dit même que le using n'est pas nécessaire...

Que pasa señor ?
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
Hmm, ça a été rajouté pour C# 5.0 dans .NET 4.5, si tu as Visual Studio 2013, ça doit fonctionner…
Tu peux vérifier que ton projet est configuré pour utiliser le Framework 4.5 au minimum ?
avatarLe scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
Ahah, tu poutres, le pire c'est que j'ai bien pensé à une question de version (j'avais mis .NET 4 minimum), mais je me suis dit que c'était sûrement pas ça tritop
De plus, quand j'ai fait semblant de commencer à chercher de ce côté, j'ai regardé vite fait la doc, et je suis passé à côté de l'info de version. Bref, j'ai eu tout faux sur une bêtise ridicule. Merci encore. smile



Dans la doc, je ne comprends pas ça :
public event PropertyChangedEventHandler PropertyChanged;
...
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

Pourquoi ce n'est pas écrit PropertyChanged.Invoke(...); ?
J'ai pas dû assez me pencher sur les events pour comprendre, faut que j'y revienne...

Merci d'avance.


edit -> hmmmm... ça utiliserait l'opérateur surchargé (), qui doit appeler Invoke j'imagine ?
Je vais commencer à lire https://msdn.microsoft.com/en-us/library/aa645739%28v=vs.71%29.aspx , malheureusement il est marqué outdated (VS 2003)

ps -> J'ai trouvé ça : https://msdn.microsoft.com/en-us/library/awbftdfh.aspx Ca devrait être pas mal. smile
avatar<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !
En gros, si tu as compris ce qu'était une propriété, un événement c'est un élément assez similaire, sauf qu'au lieu de proposer get/set, il propose add/remove. (Et en théorie seulement, d'autres trucs genre "raise" mais je n'ai jamais vu aucun langage l'implémenter: Non, apparemment, c'est utilisable en C++/CLI)

En plus de ça, quand tu déclares un événement sans spécifier manuellement add et remove, alors à l'intérieur de la classe qui déclare l'événement, le nom de l'événement est aliasé avec celui du champ sous-jacent.
Du coup, dans ta classe, PropertyChanged est à la fois l'événement PropertyChanged de type PropertyChangedEventHandler et le champ PropertyChanged de type PropertyChangedEventHandler. (C'est ce que Microsoft appelle les "field-like events")

Un delegate (par exemple de type PropertyChangedEventHandler) étant la version objet d'un pointeur de fonction, tu peux l'invoquer avec la méthode Invoke qui est déjà bien typée, mais tu peux aussi omettre la partie .Invoke. C'est la façon habituelle de faire en C#. (Le compilateur appellera Invoke de toutes façons, c'est juste du sucre syntaxique)

Note que tu peux aussi appeler un delegate via DynamicInvoke si tu connais les paramètres sans connaître le type delegate exact. Mais c'est rarement utile en vrai.
avatarLe scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
D'une manière générale on préfère éviter DynamicInvoke, il me semble.

Aussi, .Invoke devient nécéssaire quand on utilise la "null propagation". C'est juste du syntaxic sugar qui transforme:
event Action<int> SomeEvent;

// ...

// On vérifie si la queue est nulle (mais += fonctionne, pas besoin d'initialisation!)
if (SomeEvent != null)
    SomeEvent(0);
event Action<int> SomeEvent;

// ...

SomeEvent?.Invoke(0);

Je suppose que créer l'opérateur ?(...) avait l'air idiot (en plus de poser des problèmes avec l'opérateur ternaire) grin