Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bien le bonjour,
Je rencontre des difficultés avec une barre de scrolling horizontal sur ma datawindow.
En effet, ma datawindow affiche pas loin de 20 colonnes : selon la résolution, seules certaines d'entre elles sont visibles par l'utilisateur. Je veux donc lui fournir une barre de défilement horizontale pour qu'il puisse afficher les colonnes qu'il ne voit pas...
Dans ma fenêtre qui héberge ma datawindow, je fais un clic sur la datawindow. Ensuite je coche les propriétés : HScrollBar, VScrollBar, LiveScroll. Ainsi il aura une barre de défilement horizontale, une barre de défilement verticale, et même la possibilité de scroller avec la molette de sa souris.
Voici ce que j'obtiens : (screens fournis ci-après)
- Screen 2 : Ma barre de défilement horizontale n'apparait pas dès que nécessaire : si je réduis la largeur de la fenêtre, alors certaines colonnes ne sont plus visibles mais la barre de défilement n'apparait pas. Ca me perturbe et je ne comprends pas le problème.
- Screen 3 : Ma barre de défilement horizontale est à moitié "mangée" par la fenêtre. Cela survient même si je laisse un écart entre le bas de ma fenêtre et le bas de ma datawindow. Yaurait-il une astuce de sioux pour que ça s'affiche bien ? Je n'ai que cette datawindow dans me fenêtre.
Je vous remercie pour vos conseils, idées, suggestions, ...
Dernière modification par Nyphel (15-09-2008 15:14:47)
Hors ligne
Bonjour,
La barre de scrolling horizontale apparaît uniquement que si la taille du contrôle datawindow posé dans ta fenêtre ne permet pas l'affichage de la totalité des colonnes (indépendamment de la taille de la fenêtre, ton contrôle datawindow est en fait plus grand que ta fenêtre).
Pour résoudre ton problème, il faut ajuster dynamiquement la taille de ton contrôle datawindow à la taille de ta fenêtre en encodant l'événement resize de ta fenêtre :
dw_1.Width = this.Width - 100 dw_1.Height = this.Height - dw_1.Y - 150
Hors ligne
En effet, ça fonctionne plutôt bien !
J'avoue ne pas comprendre : j'ai le code suivant dans l'event resize() de mon ancêtre de fenêtres
IF IsValid( idw_datawindow ) THEN idw_datawindow.Event dynamic ue_resize( this.workspacewidth(), this.workspaceheight() ) END IF
workspacewidth() :
Returns the width of the workspace area (in PowerBuilder units) in windowname.
Cela ne devrait-il pas fonctionner aussi bien ? :-o
Hors ligne
Lors de la retaille de ta fenêtre tu déclenches uniquement un événement personnalisé de ta dawindow (ue_resize).
Pour retailler ta datawindow, il faut donc ajouter un événement personnalisée à ta datawindow ue_resize et ajouter du code proche de celui que je t'ai indiqué pour retailler le contrôle.
Hors ligne
Oh oui d'accord !
Hors ligne
Finalement un problème similaire persiste :
A l'ouverture de ma fenêtre (postopen() event) je décide de masquer les colonnes les plus "à droite", celles notamment pour lesquelles il pouvait être nécessaire d'utiliser la barre de défilement. Dès lors toutes mes colonnes sont visibles par l'utilisateur, mais ma datawindow est si grande qu'il y a plein d'espace vide qui me dérange : je réduis donc la largeur de ma datawindow pour qu'elle fasse juste le largeur nécessaire.
Voici le code source utilsié :
// Masquage des colonnes dw_perso.object.A_t.visible = false dw_perso.object.B_t.visible = false dw_perso.object.C_t.visible = false dw_perso.object.D_t.visible = false dw_perso.object.A.visible = false dw_perso.object.B.visible = false dw_perso.object.C.visible = false dw_perso.object.D.visible = false // Déplacement des colonnes pour que la datawindow ne les considère pas "hors champ" dw_perso.object.A_t.x = 0 dw_perso.object.B_t.x = 0 dw_perso.object.C_t.x = 0 dw_perso.object.D_t.x = 0 dw_perso.object.A.x = 0 dw_perso.object.B.x = 0 dw_perso.object.C.x = 0 dw_perso.object.D.x = 0 // Redimensionnement de la datawindow dw_perso.width = long(dw_perso.object.Z.x) + long(dw_perso.object.Z.width) + 15
Voici le avant/après :
Comme vous pouvez le constater, j'ai une énorme barre de défilement horizontale qui me permet d'aller voir ce qui se passe très loin dans ma datawindow... Alors que les champs sont masqués et ont été déplacé en position 0. Je ne comprends pas le problème :-/
Hors ligne
Bonjour,
De souvenir, il faut mettre la largeur des colonnes à zéro Width = 0. Il n'est pas utile de repositionner ta colonne à la position 0.
Dans ton cas, il suffit donc de remplacer la modification de la propriété X par Width.
Hors ligne
Bonsoir Buck et merci pour ta réponse !
Il semblerait toutefois que cela ne change rien dans mon cas (Pb 10.2.0 build 8075).
Hors ligne
J'ai extrait une partie de mon code qui réalise cette opération. Il faut évidemment l'adapter à ta situation :
FOR li_j = 1 TO nAllCols ls_statut = this.describe( sAllCols[ li_j ] + '.Visible') // Attention, l'attribut visible n'est pas forcément 0 ou 1, si on attribue une formule, le champ à le format suivant : // guillemet ouvrant + Attribut de visibilite 0 ou 1 + tabulation séparatrice + formule + guillemet fermant IF len(ls_statut) > 1 THEN ls_statut = Mid(ls_statut, 2, 1) // On extrait l'attribut de visibilité pour les colonnes ayant un attribut de // visibilité avec une formule IF ls_statut = '1' THEN sAttribut += sAllCols[ li_j ] + '.Visible=0 ' + sAllCols[ li_j ] + '.Width=0 ' sAttribut += sAllCols[ li_j ] + '_t.Visible=0 ' + sAllCols[ li_j ] + '.Width=0 ' END IF NEXT sError = This.Modify( sAttribut )
J'applique le Modify en une seule fois pour l'ensemble des colonnes (fonctionne sous PB 9.0.3.8565 et PB 11.2.8616)
Hors ligne
il y peut-être un contrôle caché qq part...
Hors ligne
J'ai bien vérifié, en sélectionnant mes controls un à un dans l'onglet "control list", mais tout est bien à sa place et rien n'est caché ou positionné tout à droite ;)
J'ai aussi tenté d'utiliser du Modify et du SetRedraw, mais cela ne change absolument rien :
dw_suspect_tr.setredraw(false) dw_perso.modify('A_t.visible=0') dw_perso.modify('B_t.visible=0') dw_perso.modify('C_t.visible=0') dw_perso.modify('D_t.visible=0') dw_perso.modify('A.visible=0') dw_perso.modify('B.visible=0') dw_perso.modify('C.visible=0') dw_perso.modify('D.visible=0') dw_perso.modify('A_t.width=0') dw_perso.modify('B_t.width=0') dw_perso.modify('C_t.width=0') dw_perso.modify('D_t.width=0') dw_perso.modify('A.width=0') dw_perso.modify('B.width=0') dw_perso.modify('C.width=0') dw_perso.modify('D.width=0') dw_perso.modify('A_t.x=0') dw_perso.modify('B_t.x=0') dw_perso.modify('C_t.x=0') dw_perso.modify('D_t.x=0') dw_perso.modify('A.x=0') dw_perso.modify('B.x=0') dw_perso.modify('C.x=0') dw_perso.modify('D.x=0') dw_perso.setredraw(true)
Dernière modification par Nyphel (16-09-2008 07:01:11)
Hors ligne
Bonjour,
De souvenir, ce comportement me rappelle quelque chose lorsque j'ai mis au point mon user objet permettant de gérer mes listes.
Peux tu essayer d'appliquer le modify en une seule fois sur la colonne et son en-tête :
integer li_i string ls_modify string ls_col[] = { "A", "B", "C", "D" } FOR li_i = 1 TO UpperBound(ls_col) ls_modify += ls_col[li_i] + ".visible=0 " + ls_col[li_i] + ".Width=0 " + ls_col[li_i] + "_t.visible=0 " + ls_col[li_i] + "_t.Width=0 " NEXT dw_perso.modify (ls_modify)
Hors ligne
Merci pour ton aide Buck !
Avec ce code j'ai bien mes 4 en-têtes/colonnes masquées, mais ma barre de scrolling horizontale demeure présente comme si elles étaient visibles.
Je ne comprends pas et j'envisage même de masquer/afficher la barre de scrolling manuellement... Mais ça serait dommage de calculer la dernière colonne visible, sa position, sa largeur, de chercher à savoir si elle est bien visible dans la datawindow ou si elle dépasse, etc... D'autant plus que ce calcul devrait aussi être effectué sur le resize :-/
Tiens je viens de gagner 500 pépites à la loterie, alors je te les donne !
Dernière modification par Nyphel (16-09-2008 08:15:17)
Hors ligne
Je m'y suis donc pris différemment :
- Je me suis fait une petite fonction qui regarde quelles sont les colonnes affichées et modifie la largeur de la datawindow pour qu'elle puisse toute les afficher. Toutefois, la largeur de la DW n'excède jamais celle de la fenêtre, donc il est possible que toutes les colonnes ne soient pas visibles.
- Une seconde fonction gère la barre de scrolling horizontale, en comparant la largeur nécessaire à la datawindow pour que toutes ses colonnes visibles soient affichées, et la largeur actuelle de la fenêtre.
- Lorsque j'ouvre ma fenêtre, je fais appel successivement à mes 2 fonctions : la datawindow est resizée pour coller au contenu, et la barre de scrolling apparait si nécessaire.
- Lorsque je redimensionne ma fenêtre, je fais de nouveau appel à mes 2 fonctions : la datawindow est resizée pour coller au contenu, et la barre de scrolling apparait si nécessaire.
Ce que je remarque c'est que dès que ma barre de scrolling horizontal devient visible, alors je peux scroller très loin sur la droite même si ma datawindow est resizée pour coller au contenu (je scroll donc sur du vide, après ma dernière colonne visible). Bref ça fait comme avant, sauf que maintenant ça ne le fait que lorsqu'il y a besoin de scroller ;). Ca progresse, mais ça demeure étrange.
Je ne suis pas certain que l'on parvienne à résoudre ce problème...
Je fournis ci-après le code source, il servira peut-être à quelqu'un qui rencontre ce soucis, ou peut-être y trouverez vous à redire ;)
Voici ma fonction qui récupère la largeur nécessaire à la datawindow :
of_get_dw_necessary_width()
// Return the necessary width for displaying all visible columns of datawindow dw_suspect_tr // This function may be used to compare the DW necessary width and the DW current width long ll_nb_cols long ll_i string ls_col[] long ll_current_x = 0, ll_current_width = 0 long ll_max_x = 0, ll_max_width = 0 long ll_final_dw_width // Generate the table of columns (Not the displayed ones, but the ones declared in 'Column specification' tab) ll_nb_cols = long(dw_perso.Object.DataWindow.Column.Count) FOR ll_i = 1 TO ll_nb_cols ls_col[ll_i] = dw_perso.Describe("#"+string(ll_i)+".Name") NEXT // Give a look at each column of the datawindow FOR ll_i = 1 TO UpperBound(ls_col) // If the column is visible IF long(dw_perso.describe(ls_col[ll_i] + ".visible")) = 1 THEN // Get X position of the column ll_current_x = long(dw_perso.describe(ls_col[ll_i] + ".x")) ll_current_width = long(dw_perso.describe(ls_col[ll_i] + ".width")) // If this column is the most on the right, save its attributes IF ll_current_x > ll_max_x THEN ll_max_x = ll_current_x ll_max_width = ll_current_width END IF END IF NEXT // Compute the datawindow width that is necessary to display all visible columns ll_final_dw_width = ll_max_x + ll_current_width return ll_final_dw_width
Voici la fonction qui permet de directement resizer la datawindow à sa largeur nécessaire :
of_set_dw_necessary_width()
// Set the necessary width for displaying all visible columns in datawindow dw_perso // Does not extend it over the window current width long ll_final_dw_width // Compute the datawindow width that is necessary to display all visible columns ll_final_dw_width = of_get_dw_necessary_width() + 15 // Set the new DW width long ll_window_width ll_window_width = this.width IF ll_final_dw_width < (ll_window_width - 50) THEN dw_suspect_tr.width = ll_final_dw_width ELSE dw_suspect_tr.width = ll_window_width - 50 // Margin for vertical scroll bar END IF
Voici ma petite fonction qui gère ma barre de scrolling horizontale :
of_manage_hscrollbar_visibility()
// Hide or display horizontal scrolling bar // Note : 50 is the width used for vertical scroll bar display, on the right of the datawindow long ll_dw_necessary_width long ll_window_width ll_dw_necessary_width = of_get_dw_necessary_width() ll_window_width = this.width IF ll_window_width < (ll_dw_necessary_width) THEN dw_perso.hscrollbar = true ELSE dw_perso.hscrollbar = false END IF
Enfin voici mon resize() event :
of_set_dw_necessary_width()
dw_perso.Height = this.Height - dw_suspect_tr.Y - 150
of_manage_hscrollbar_visibility()
Dernière modification par Nyphel (16-09-2008 11:45:37)
Hors ligne
J'ai vérifié sur mes listes le fait de masquer une colonne fait disparaître automatiquement la barre de scrolling horizontale si la taille du contrôle datawindow est suffisante pour afficher l'ensemble des colonnes visibles.
A mon point de vue, tu dois avoir un objet qui traîne à l'extrême droite de ta datawindow (du genre une bitmap coincé entre 2 bandes, static text ou autres). Tu peux vérifier à partir de la liste des contrôles présents dans la datawindow qu'il n'y a pas un objet parasite qui traîne.
Le mieux est peut être d'essayer de reconstruire la datawindow.
ex : Masquage d'une colonne en cliquant sur l'en-tête d'une colonne avec l'horizontale scrollbar présente :
Après le masquage, l'espace du contrôle est suffisant pour afficher l'ensemble des colonnes, la scrollbar a automatiquement disparu sans intervention dans le code :
Hors ligne
Wout ! Quelle belle fenêtre !
J'ai bien contrôlé qu'aucun contrôle ne trainait (ma datawindow est assez basique, et j'ai cliqué sur chaque élément de la control list pour vérifier leur position).
J'essaierai de la reconstruire dès que j'aurai un moment.
Merci encore pour ton aide !
Hors ligne