IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Presentation Foundation Discussion :

[Custom Control] Comment résoudre un problème d'affichage uniquement dans Blend ?


Sujet :

Windows Presentation Foundation

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 68
    Points : 43
    Points
    43
    Par défaut [Custom Control] Comment résoudre un problème d'affichage uniquement dans Blend ?
    Bonjour,

    Je me suis mis il y a quelques jours au WPF, mon premier essai est un projet custom control contenant deux contrôles :

    - NavBar dérivé de TabControl
    - NavBarItem dérivé de TabItem

    Ils sont tous les deux modifiés et marche correctement, mais j'ai cependant un problème :

    Lorsque j'ajoute un contrôle NavBar à partir de Blend 2.0 (en mode design), ce dernier me crée automatiquement deux TabItem à l'intérieur de mon contrôle NavBar. Hors ce sont les NavBarItem qui sont prévu comme enfants de mon contrôle NavBar.

    Je suppose que je dois quelque part dans mon Custom Control Project déclarer que l'enfant par défaut pour le contrôle NavBar est NavBarItem, mais où ?

    Merci d'avance pour votre aide.

  2. #2
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Salut,

    Citation Envoyé par choas
    mais où ?
    Personnellement, je ne pourrais pas t'aider sans le code. Peut-être que certains ont déjà eu ce cas de figure et pourront te le dire sans le voir...
    Si tu le mets je jetterai un coup d'oeil

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 68
    Points : 43
    Points
    43
    Par défaut
    Actuellement il n'y a aucun code C#, c'est juste du XAML. Pour l'instant je n'ai fait qu'un restyling du TabControl, je n'ai pas ajouter d'évenements ou de propriétés supplémentaires. Voilà le code XAML du contrôle NavBar (héritant du TabControl) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
     
        <SolidColorBrush x:Key="NavBarForeground" Color="#FF204D89"/>
     
        <LinearGradientBrush x:Key="NavBarBackground" EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#FFD9EDFF" Offset="0"/>
            <GradientStop Color="#FFC0DEFF" Offset="0.445"/>
            <GradientStop Color="#FFC0D9FB" Offset="1"/>
            <GradientStop Color="#FFAFD1F8" Offset="0.53"/>
        </LinearGradientBrush>
     
        <Style TargetType="{x:Type local:SILU_NavBar}">
            <Setter Property="Foreground" Value="{StaticResource NavBarForeground}"/>
            <Setter Property="Background" Value="{StaticResource NavBarBackground}"/>
            <Setter Property="BorderBrush" Value="{x:Static Microsoft_Windows_Themes:ClassicBorderDecorator.ClassicBorderBrush}"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Margin" Value="0"/>
            <Setter Property="Padding" Value="1"/>
            <Setter Property="MinWidth" Value="30"/>
            <Setter Property="MinHeight" Value="10"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:SILU_NavBar}">
                        <Grid ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition x:Name="ColumnDefinition0"/>
                                <ColumnDefinition x:Name="ColumnDefinition1" Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition x:Name="RowDefinition0" Height="Auto"/>
                                <RowDefinition x:Name="RowDefinition1" Height="*"/>
                            </Grid.RowDefinitions>
                            <Grid x:Name="ContentPanel" Grid.Column="0" Grid.Row="1" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
                                <Microsoft_Windows_Themes:ClassicBorderDecorator Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderStyle="Raised" BorderThickness="{TemplateBinding BorderThickness}">
                                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="2,2,2,2" x:Name="PART_SelectedContentHost" ContentSource="SelectedContent"/>
                                </Microsoft_Windows_Themes:ClassicBorderDecorator>
                            </Grid>
                            <StackPanel HorizontalAlignment="Stretch" Margin="0,-2,0,0" x:Name="HeaderPanel" VerticalAlignment="Bottom" Width="Auto" Height="Auto" Grid.Row="1" IsItemsHost="True"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="TabStripPlacement" Value="Bottom">
                                <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
                                <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                                <Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/>
                            </Trigger>
                            <Trigger Property="TabStripPlacement" Value="Left">
                                <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
                                <Setter Property="Grid.Column" TargetName="ContentPanel" Value="1"/>
                                <Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
                                <Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
                                <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                                <Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
                            </Trigger>
                            <Trigger Property="TabStripPlacement" Value="Right">
                                <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
                                <Setter Property="Grid.Column" TargetName="ContentPanel" Value="0"/>
                                <Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/>
                                <Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/>
                                <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                                <Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="{DynamicResource
                                    {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    Je me demande si il ne faudrais pas implémenter une de ces méthodes au niveau de mon StackPanel pour définir le child de mon contrôle en tant que NavBarItem.

    http://msdn.microsoft.com/en-us/libr...icalchild.aspx

    Maintenant j'avoue ne pas être très certain de ce que j'avance du haut de mes 3 jours d'expérience avec le .NET 3.5 lol.

    J'espère toujours de l'aide de votre part

  4. #4
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Je vois bien la problématique :
    Dire au NavBar que ces items sont des NavBarItem et non des TabItem.

    Après pour ce qui est d'y répondre, c'est autre chose

    Dans la doc msdn :

    il y a ça :
    Citation Envoyé par msdn
    [TemplatePartAttribute(Name = "PART_SelectedContentHost", Type = typeof(ContentPresenter))]
    [StyleTypedPropertyAttribute(Property = "ItemContainerStyle", StyleTargetType = typeof(TabItem))]
    public class TabControl : Selector
    C'est peut-être là que tout se joue ? Il faut peut-être le redéclarer.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 68
    Points : 43
    Points
    43
    Par défaut
    J'ai essayer de déclarer cette ligne sans grande conviction (je ne sais pas comment on l'utilise), mais ca n'a rien donner.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    [TemplatePartAttribute(Name="NavBarItem", Type=typeof(NavBarItem))]
     
        public class NavBar : TabControl 
        {
            static NavBar()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(NavBar), new FrameworkPropertyMetadata(typeof(NavBar)));
            }
     
     
        }
    Je sèche toujours

  6. #6
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    binoo parlait de l'autre attribut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [StyleTypedPropertyAttribute(Property = "ItemContainerStyle", StyleTargetType = typeof(NavBarItem))]

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 68
    Points : 43
    Points
    43
    Par défaut
    Ah ok, malheureusement ca ne donne rien non plus comme ca.

    Je n'ai aucune erreurs de compilation mais lorsque j'ajoute un NavBar dans Blend il me met toujours deux tabControl standards dedans par défaut.

    Le problème parait tellement bète que j'ai l'impression que la solution doit l'être tout autant mais je vois pas

    Désolé d'insister mais je suis désespéré, je cherche depuis 2 jours non stop et je ne trouve rien ...

    Je ne sais même pas de quel côté regarder, le XAML ? le C# ?

    Je suis obliger de trouver une solution, si vous avez des informations même incomplètes je suis preneur.

    Merci d'avance.

  8. #8
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Salut,

    Ba j'ai jamais tenté ça encore . Et là je n'ai pas vraiment le temps de regarder plus que ça...

    Jusqu'à présent les TabControl et TabItem, je me suis contenté de les re-designer. D'ailleurs si c'est ton unique objectif "re-designer", il faut savoir que passer par un CustomControl n'est pas nécessaire. Est-ce ce ton cas ?

    Si oui, les styles et template sont suffisants.
    Car pour info, ces styles peuvent être appliqués à tous les TabControl et TabItems d'une application en mettant au niveau du style une Key du type :
    {x:Type TabControl}

  9. #9
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Il faudrait p-e redéfinir l'attribut [ContentPropertyAttribute("Items")], faut voir....

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 68
    Points : 43
    Points
    43
    Par défaut
    Non mon but n'est pas uniquement du restyling, j'ai déjà rajouter quelques propriétés et j'ai encore quelques trucs a modifier. Mais il faut premier que je passe outre ce problème.

    Le truc, c'est que dans VS 2008 lorsque j'ajoute un contrôle NavBar par le designer, lui ne me crée pas de tabItem il le laisse vierge, ce qui est acceptable comme solution pour moi.

    C'est dans Blend qu'il m'ajoute automatiquement deux tabItem, j'ai essayer d'overrider pas mal d'évènements du TabControl dans mon NavBar mais je ne trouve pas celui qui est activé quand Blend ajoute les tabItem.

    Si je parvenais à le trouver, je pourrais au moins l'empêcher de le faire, mais j'ai bien l'impression que c'est simplement Blend qui ajoute du code XAML sans déclencher d'évènements particuliers.

    Pour ce qui est du [ContentPropertyAttribute("Items")], tu aurais un exemple de son utilisation ?

    Merci pour votre aide.

    Voilà j'ai bien avancé, j'ai trouvé un problème similaire sur le forum US de MSDN. Voilà donc ce qu'il faut faire :

    Simplement overrider deux méthodes du TabControl.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     protected override bool IsItemItsOwnContainerOverride(object item)
            {
                return item is NavBarItem;
            }
     
    protected override DependencyObject GetContainerForItemOverride()
            {
                return new NavBarItem();
            }
    Mais il me reste un problème encore une fois vraiment spécifique a Blend, lorsque j'ajoute le control en mode design, il est maintenant correctement créé avec des NavBarItem au niveau visuel, mais au niveau du XAML Blend continue de me créé des TabItem comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <NavBar:NavBar IsSynchronizedWithCurrentItem="True" Margin="91,111,247,79">
        <TabItem Header="TabItem">
            <Grid/>
        </TabItem>
        <TabItem Header="TabItem">
            <Grid/>
        </TabItem>
    </NavBar:NavBar>
    Ce qui entraine comme problème que si on modifie les propriétés (le Header par exemple) rien ne se passe étant donné que les TabItem ne sont pas les NavBarItem. C'est un peu tordu je trouve, car les NavBarItem sont bien présents au niveau visuel de mon contrôle alors que dans le XAML j'ai des TabItem

    Je ne comprend pas comment Blend fonctionne...

  11. #11
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Citation Envoyé par choas
    Je ne comprend pas comment Blend fonctionne...
    Pas mieux

    Et quel est son comportement lorsque tu vas effectuer un clic droit sur ton NavBar ? Est-ce qu'il te dit ajouter un NavBarItem ou un TabItem ou rien ? Là je n'imagine pas vraiment comment Blend s'en sort ? Si tu peux tester

  12. #12
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut


    Sachant que pour afficher un visuel, Blend utilise le code XAML, je comprend pas comment tu peux avoir un rendu différent de ton XAML....

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 68
    Points : 43
    Points
    43
    Par défaut
    Avec un click droit j'ai l'option "Add TabItem", elle ajoute un NavBarItem au niveau visuel mais un TabItem dans le XAML ...

    J'ai l'impression que en plus de l'override des deux methodes plus haut, je doit également définir le template des items de mon content presenter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    <ControlTemplate TargetType="{x:Type local:NavBar}">
                        <Grid ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition x:Name="ColumnDefinition0"/>
                                <ColumnDefinition x:Name="ColumnDefinition1" Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition x:Name="RowDefinition0" Height="Auto"/>
                                <RowDefinition x:Name="RowDefinition1" Height="*"/>
                            </Grid.RowDefinitions>
                            <Grid x:Name="ContentPanel" Grid.Column="0" Grid.Row="1" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
                                <Microsoft_Windows_Themes:ClassicBorderDecorator Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderStyle="Raised" BorderThickness="{TemplateBinding BorderThickness}">
                                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="2,2,2,2" x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" />
                                </Microsoft_Windows_Themes:ClassicBorderDecorator>
                            </Grid>
                            <StackPanel HorizontalAlignment="Stretch" Margin="0,-2,0,0" x:Name="HeaderPanel" VerticalAlignment="Bottom" Width="Auto" Height="Auto" Grid.Row="1" IsItemsHost="True"/>
                        </Grid>
    </ControlTemplate>
    Mais j'avoue que la je décroche, j'ai déjà du partir d'un exemple existant pour établir ce code XAML, donc j'ai un peu de mal a comprendre comment définir un template et autres avec mes UNE semaine d'expérience en WPF

    En sachant que ce code est appliqué à un contrôle NavBar dérivant d'un TabControl et devant contenir des contrôles NavBarItem (contenu dans le même projet), peut-être que l'un de vous peut m'aider ?

  14. #14
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Si tu veux avoir l'option "Add NavBarItem" sur la clic droit de ton control, dans Blend, il faut que tu ajoutes l'attribut suivant sur ton controle NavBar:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(NavBarItem))]
    Tu auras ainsi l'option correspondante sur le clic droit, sur ton contrôle, et cela te générera le code XAML adéquat

    Attention cependant: par défaut, le XAML généré insère une grille dans le TabItem:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <local:MyTabItem Header="MyTabItem">
            		<Grid/>
            	</local:MyTabItem>

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 68
    Points : 43
    Points
    43
    Par défaut
    Salut,

    Effectivement, avec la ligne de code que tu m'as donné lorsque je fais un click droit sur mon NavBar il me permet d'ajouter des NavBarItem. C'est un bon point.

    Malheureusement lorsque j'ajoute un NavBar sur une form, c'est toujours deux TabItem qu'il m'ajoute par défault. Où est défini qu'il faut ajouter deux TabItem par défault ? Personnelement si je pouvais mettre zero à la place de deux ca règlerais le problème plus facilement ...

    Mais je ne suis pas sûre que la quantité de TabItem à ajouter est définie dans le code du contrôle puisque sous VS 2008 il n'en ajoute aucun.

  16. #16
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Citation Envoyé par choas Voir le message
    Malheureusement lorsque j'ajoute un NavBar sur une form, c'est toujours deux TabItem qu'il m'ajoute par défault. Où est défini qu'il faut ajouter deux TabItem par défault ? Personnelement si je pouvais mettre zero à la place de deux ca règlerais le problème plus facilement ...
    Ca doit être le même principe que précédemment: faut juste trouver la propriété qu'il utilise pour initialiser le controle.

Discussions similaires

  1. Réponses: 8
    Dernier message: 20/05/2010, 01h59
  2. Réponses: 12
    Dernier message: 27/08/2007, 13h33
  3. Réponses: 3
    Dernier message: 19/05/2006, 16h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo