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 :

Comment créer un GroupBox contenant une CheckBox dans le Header ?


Sujet :

Windows Presentation Foundation

  1. #1
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut Comment créer un GroupBox contenant une CheckBox dans le Header ?
    Bonjour,

    J'ai créé un DataTemplate pour afficher certains de mes objets persos.
    Ce DataTemplate doit contenir un GroupBox contenant une CheckBox dans le Header (afin d'activer ou désactiver le contenu du GroupBox).

    L'état de cette CheckBox doit être bindé sur une propriété de l'objet affiché dans ce GroupBox personnalisé.

    Comment puis-je faire simplement pour avoir ça ?
    Est-ce faisable juste avec un style ? (notamment le lien entre l'état de ma CheckBox et une des propriétés de mon objet)
    Ou bien dois-je forcément créer un UserControl tout compliqué ?

    Merci !

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Par défaut
    voic pour info du code pour mettre une combo dans une colonne d'un listview
    je sais pas si tca peut t'aider mais bon
    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
     
     <ListView ItemsSource="{Binding Source={StaticResource LogsFilter}}" 
                      x:Name="listView1" 
                      ItemContainerStyle="{StaticResource myListViewItemStyle}"  
                      >
                <ListView.View>
                    <GridView AllowsColumnReorder="True" >
                        <Local:FixedWidthGridViewColumn                                    
                                        x:Name="colType"
                                        FixedWidth="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}, 
                                        Path=ItemContainerStyle, Converter={StaticResource WidthConv}, ConverterParameter=15}" 
                                        >
                            <GridViewColumnHeader>
                                <Grid Width="{Binding ElementName=colType, Path=FixedWidth}"                                      
                                           Height="20">
                                    <ComboBox HorizontalAlignment="Center"
                                              ItemsSource="{Binding Source={StaticResource LevelValues}}"   
                                              Style="{StaticResource MyComboBoxStyle}"
                                              x:Name="Combobox1"                                          
                                              >
                                        <ComboBox.ItemTemplate>
                                            <DataTemplate>
                                                <StackPanel Orientation="Horizontal">
                                                    <Ellipse Height="18" Width="18" 
                                                             Stroke="{Binding Converter={StaticResource LevelStrokeConverter}}"
                                                             >
                                                        <Ellipse.Fill>
                                                            <RadialGradientBrush GradientOrigin="0.312,0.32">
                                                                <GradientStop Color="#FFFDFDFD" Offset="0"/>
                                                                <GradientStop Color="{Binding Converter={StaticResource LevelExtendedConverter}}" Offset="1"/>
                                                            </RadialGradientBrush>
                                                        </Ellipse.Fill>
                                                    </Ellipse>
                                                    <CheckBox Margin="2,2,2,2" x:Name="alpha1" 
                                                              Content="{Binding}" Tag="{Binding}" 
                                                              Click="CheckBox_Click"
                                                              VerticalAlignment="Center"/>
                                                </StackPanel>
                                            </DataTemplate>
                                        </ComboBox.ItemTemplate>
                                    </ComboBox>                                
                                </Grid>
                            </GridViewColumnHeader>
                            <GridViewColumn.CellTemplate>
                                <DataTemplate >
                                    <StackPanel Orientation="Horizontal" >
                                        <Ellipse Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}, Path=ActualHeight, Converter={StaticResource ReduceConverter}}" 
                                                 Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}, Path=ActualHeight, Converter={StaticResource ReduceConverter}}"
                                                 Stroke="Black"
                                                 >
                                            <Ellipse.Fill>
                                                <RadialGradientBrush GradientOrigin="0.312,0.32">
                                                    <GradientStop Color="#FFFDFDFD" Offset="0"/>
                                                    <GradientStop Color="{Binding Path=Level, Converter={StaticResource LevelColorConverter}}" Offset="1"/>
                                                </RadialGradientBrush>
                                            </Ellipse.Fill>
                                        </Ellipse>
                                    </StackPanel>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </Local:FixedWidthGridViewColumn >
                        <GridViewColumn Header="{DynamicResource COL_DATE}" Width="Auto" DisplayMemberBinding="{Binding Path=Date}"/>
                        <GridViewColumn Header="{DynamicResource COL_MESSAGE}" Width="1050" 
                                        HeaderContainerStyle="{StaticResource HeaderLeft}"
                                        DisplayMemberBinding="{Binding Path=Message}"/>
                    </GridView>
                </ListView.View>
            </ListView>
    ceci etant quand on veut mettre une combo dans un header
    on fait
    <composant.header>
    <combobox/>
    </composant.header>

  3. #3
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Ouais, et puis tu utilises une ressource statique pour remplir les valeurs de ta ComboBox, alors que moi ce que j'aimerai c'est utiliser une propriété d'une propriété (y'a pas de doublon ) de mon UserControl.

    De plus, comme je dois utiliser cette GroupBox à de nombreuses reprises, j'aimerai bien avoir un truc centralisé (genre un Style, un DataTemplate ou un UserControl).

    Je sais j'en demande beaucoup

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Citation Envoyé par seiryujay Voir le message
    De plus, comme je dois utiliser cette GroupBox à de nombreuses reprises, j'aimerai bien avoir un truc centralisé (genre un Style, un DataTemplate ou un UserControl).
    Fais toi un petit Custom Control

  5. #5
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Ce que j'ai fait et qui marche pas mal (même s'il reste un petit détail à corriger), c'est :
    - créer une classe CheckableGroupBox qui étend GroupBox et dans laquelle j'ai rajouté ma DependencyProperty "IsChecked"
    - ajouter à mon dictionnaire de ressources le Style suivant
    Code xml : 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
    73
    74
    75
    76
    77
     
        <Style TargetType="{x:Type utils:CheckableGroupBox}">
            <Setter Property="BorderBrush"
                    Value="#D5DFE5" />
            <Setter Property="BorderThickness"
                    Value="1" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type utils:CheckableGroupBox}">
                        <Grid SnapsToDevicePixels="true">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                                <RowDefinition Height="6" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="6" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="6" />
                            </Grid.ColumnDefinitions>
                            <Border Grid.Column="0"
                                    Grid.ColumnSpan="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="Transparent"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="4" />
                            <ContentPresenter Margin="{TemplateBinding Padding}"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                              Grid.Column="1"
                                              Grid.ColumnSpan="2"
                                              Grid.Row="2" />
                            <Border Grid.ColumnSpan="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    BorderBrush="White"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="4">
                                <Border.OpacityMask>
                                    <MultiBinding Converter="{StaticResource BorderGapMaskConverter}"
                                                  ConverterParameter="7">
                                        <Binding Path="ActualWidth"
                                                 ElementName="Header" />
                                        <Binding Path="ActualWidth"
                                                 RelativeSource="{RelativeSource Self}" />
                                        <Binding Path="ActualHeight"
                                                 RelativeSource="{RelativeSource Self}" />
                                    </MultiBinding>
                                </Border.OpacityMask>
                                <Border BorderBrush="{TemplateBinding BorderBrush}"
                                        BorderThickness="{TemplateBinding BorderThickness}"
                                        CornerRadius="3">
                                    <Border BorderBrush="White"
                                            BorderThickness="{TemplateBinding BorderThickness}"
                                            CornerRadius="2" />
                                </Border>
                            </Border>
                            <Border x:Name="Header"
                                    Grid.Column="1"
                                    Grid.Row="0"
                                    Grid.RowSpan="2"
                                    Padding="3,1,3,0">
                                <StackPanel Orientation="Horizontal">
                                    <CheckBox IsChecked="{TemplateBinding IsChecked}"
                                              VerticalAlignment="Center"
                                              Width="20" />
                                    <TextBlock Text="{TemplateBinding Header}" />
                                </StackPanel>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    Ce style reprend celui d'un GroupBox normal, sauf 2 petits changements :
    - la description du Header qui est représenté par une CheckBox et un TextBlock
    - la Border "Header" est définie à la fin du ControlTemplate au lieu de l'être en 2ème position dans le template de base et ce afin d'éviter un petit désagrément qui est que lorsqu'on se positionne sur la CheckBox du Header exactement au niveau du cadre du GroupBox, la CheckBox ne prenait pas le focus et on avait beau cliquer, son état ne changeait pas.


    Mon dernier problème est que quand je modifie l'état de ma CheckBox contenue dans le Header, le contenu de ma GroupBox n'est pas grisé...
    Voilà comment je l'utilises :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
                    <utils:CheckableGroupBox x:Name="cbGroupBox"
                                             Header="Error"
                                             IsChecked="{Binding ErrorData.IsEnabled}">
                        <StackPanel x:Name="panelError"
                                    Orientation="Horizontal"
                                    IsEnabled="{Binding ElementName=cbGroupBox, Path=IsChecked}">
                        ...

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Par défaut
    ecoute en faisant ca ca marche
    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
     
    <GroupBox x:Name="cbGroupBox"
     
                      >
                <GroupBox.Header>
                    <CheckBox x:Name="check" />
                </GroupBox.Header>
                    <StackPanel x:Name="panelError"
                                    Orientation="Horizontal"
                                    IsEnabled="{Binding ElementName=check, Path=IsChecked}">
                    <ComboBox Width="150">
                        <ComboBoxItem >sdfsdfsdfsdf</ComboBoxItem>
                        <ComboBoxItem >sdfsdfsdfsdf</ComboBoxItem>
                        <ComboBoxItem >sdfsdfsdfsdf</ComboBoxItem>
                        <ComboBoxItem >sdfsdfsdfsdf</ComboBoxItem>
                        <ComboBoxItem >sdfsdfsdfsdf</ComboBoxItem>
                    </ComboBox>
                </StackPanel>
            </GroupBox>

  7. #7
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Effectivement, ta méthode marche. Je n'avais pas vu qu'on pouvait mettre directement des FrameworkElement dans la propriété Header du GroupBox.

    Par contre, maintenant que j'ai essayé de faire un CustomControl basé sur un GroupBox, j'aimerai bien le faire marcher complètement

    Tu aurais une idée de pourquoi quand je clique sur la CheckBox de mon Header, la propriété IsChecked de mon CustomControl n'est pas mise à jour ?
    Ca viendrait de l'utilisation du TemplateBinding ?

    Voici le code complet de mon CustomControl :
    1) Le C# :
    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
     
    using System.Windows.Controls;
    using System.Windows;
     
    namespace Utils
    {
        /// <summary>
        /// Class representing a GroupBox with a CheckBox in its header.
        /// </summary>
        public class CheckableGroupBox : GroupBox
        {
            static CheckableGroupBox()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckableGroupBox), new FrameworkPropertyMetadata(typeof(CheckableGroupBox)));
            }
     
     
     
     
            #region Dependency properties
     
            public static DependencyProperty IsCheckedProperty = DependencyProperty.Register(
               "IsChecked", typeof(bool), typeof(CheckableGroupBox));
     
            #endregion
     
     
     
     
            #region Properties
     
            public bool IsChecked
            {
                get { return (bool)GetValue(IsCheckedProperty); }
                set { SetValue(IsCheckedProperty, value); }
            }
     
            #endregion Properties
        }
    }
    2) Le XAML :
    Code xml : 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
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:utils="clr-namespace:Utils">
    
    
        <BorderGapMaskConverter x:Key="BorderGapMaskConverter" />
    
        <Style TargetType="{x:Type utils:CheckableGroupBox}">
            <Setter Property="BorderBrush"
                    Value="CadetBlue" />
            <Setter Property="BorderThickness"
                    Value="1" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type utils:CheckableGroupBox}">
                        <Grid SnapsToDevicePixels="true">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                                <RowDefinition Height="6" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="6" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="6" />
                            </Grid.ColumnDefinitions>
                            <Border Grid.Column="0"
                                    Grid.ColumnSpan="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="Transparent"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="4" />
                            <ContentPresenter Margin="{TemplateBinding Padding}"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                              Grid.Column="1"
                                              Grid.ColumnSpan="2"
                                              Grid.Row="2" />
                            <Border Grid.ColumnSpan="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    BorderBrush="White"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="4">
                                <Border.OpacityMask>
                                    <MultiBinding Converter="{StaticResource BorderGapMaskConverter}"
                                                  ConverterParameter="7">
                                        <Binding Path="ActualWidth"
                                                 ElementName="Header" />
                                        <Binding Path="ActualWidth"
                                                 RelativeSource="{RelativeSource Self}" />
                                        <Binding Path="ActualHeight"
                                                 RelativeSource="{RelativeSource Self}" />
                                    </MultiBinding>
                                </Border.OpacityMask>
                                <Border BorderBrush="{TemplateBinding BorderBrush}"
                                        BorderThickness="{TemplateBinding BorderThickness}"
                                        CornerRadius="3">
                                    <Border BorderBrush="White"
                                            BorderThickness="{TemplateBinding BorderThickness}"
                                            CornerRadius="2" />
                                </Border>
                            </Border>
                            <!-- La définition du Header -->
                            <Border x:Name="Header"
                                    Grid.Column="1"
                                    Grid.Row="0"
                                    Grid.RowSpan="2"
                                    Padding="3,1,3,0">
                                <StackPanel Orientation="Horizontal">
                                    <CheckBox IsChecked="{TemplateBinding IsChecked}"
                                              VerticalAlignment="Center"
                                              Width="20" />
                                    <TextBlock Text="{TemplateBinding Header}" />
                                </StackPanel>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>

    3) L'appel au composant :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                    <utils:CheckableGroupBox x:Name="ErrorGroupBox"
                                             Header="Error"
                                             IsChecked="{Binding ErrorData.IsEnabled, Mode=TwoWay}">

    Merci.

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Par défaut
    oui sans doute remplace pour voir ton binding avec un find avec un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    RelativeSource=
     {RelativeSource FindAncestor, AncestorType={x:Type CheckableGroupBox}}}"

  9. #9
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Bien joué !
    Ca marche nickel du coup.

    Voici le code final qui fonctionne :
    1) Le XAML :
    Code xml : 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
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
     
    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:utils="clr-namespace:Utils">
     
     
        <BorderGapMaskConverter x:Key="BorderGapMaskConverter" />
     
        <Style TargetType="{x:Type utils:CheckableGroupBox}">
            <Setter Property="BorderBrush"
                    Value="CadetBlue" />
            <Setter Property="BorderThickness"
                    Value="1" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type utils:CheckableGroupBox}">
                        <Grid SnapsToDevicePixels="true">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                                <RowDefinition Height="6" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="6" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="6" />
                            </Grid.ColumnDefinitions>
                            <Border Grid.Column="0"
                                    Grid.ColumnSpan="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="Transparent"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="4" />
                            <ContentPresenter Margin="{TemplateBinding Padding}"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                              Grid.Column="1"
                                              Grid.ColumnSpan="2"
                                              Grid.Row="2" />
                            <Border Grid.ColumnSpan="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    BorderBrush="White"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="4">
                                <Border.OpacityMask>
                                    <MultiBinding Converter="{StaticResource BorderGapMaskConverter}"
                                                  ConverterParameter="7">
                                        <Binding Path="ActualWidth"
                                                 ElementName="Header" />
                                        <Binding Path="ActualWidth"
                                                 RelativeSource="{RelativeSource Self}" />
                                        <Binding Path="ActualHeight"
                                                 RelativeSource="{RelativeSource Self}" />
                                    </MultiBinding>
                                </Border.OpacityMask>
                                <Border BorderBrush="{TemplateBinding BorderBrush}"
                                        BorderThickness="{TemplateBinding BorderThickness}"
                                        CornerRadius="3">
                                    <Border BorderBrush="White"
                                            BorderThickness="{TemplateBinding BorderThickness}"
                                            CornerRadius="2" />
                                </Border>
                            </Border>
                            <Border x:Name="Header"
                                    Grid.Column="1"
                                    Grid.Row="0"
                                    Grid.RowSpan="2"
                                    Padding="3,1,3,0">
                                <StackPanel Orientation="Horizontal">
                                    <CheckBox IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type utils:CheckableGroupBox}}, Path=IsChecked}"
                                              VerticalAlignment="Center"
                                              Width="20" />
                                    <TextBlock Text="{TemplateBinding Header}" />
     
                                </StackPanel>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>

    2) Le C# :
    Code c# : 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
     
    using System.Windows.Controls;
    using System.Windows;
     
    namespace Utils
    {
        /// <summary>
        /// Class representing a GroupBox with a CheckBox in its header.
        /// </summary>
        public class CheckableGroupBox : GroupBox
        {
            static CheckableGroupBox()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckableGroupBox), new FrameworkPropertyMetadata(typeof(CheckableGroupBox)));
            }
     
     
     
     
            #region Dependency properties
     
            public static DependencyProperty IsCheckedProperty = DependencyProperty.Register(
               "IsChecked", typeof(bool), typeof(CheckableGroupBox));
     
            #endregion
     
     
     
     
            #region Properties
     
            public bool IsChecked
            {
                get { return (bool)GetValue(IsCheckedProperty); }
                set { SetValue(IsCheckedProperty, value); }
            }
     
            #endregion Properties
        }
    }


    Merci pour le coup de main !

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Par défaut
    en fait y'a bcp plus simple en creusant ton code, t'es même pas oblige de faire une composant spécifique, tu peux juste travailler avec le style

    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
    73
    74
    75
    76
    77
    78
    79
    80
    <Style TargetType="{x:Type utils:CheckableGroupBox}">
            <Setter Property="BorderBrush"
                    Value="CadetBlue" />
            <Setter Property="BorderThickness"
                    Value="1" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type utils:CheckableGroupBox}">
                        <Grid SnapsToDevicePixels="true">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                                <RowDefinition Height="6" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="6" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="6" />
                            </Grid.ColumnDefinitions>
                            <Border Grid.Column="0"
                                    Grid.ColumnSpan="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="Transparent"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="4" />
                            <ContentPresenter Margin="{TemplateBinding Padding}"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                              Grid.Column="1"
                                              Grid.ColumnSpan="2"
                                              Grid.Row="2" 
                                              IsEnabled="{Binding ElementName=toto, Path=IsChecked}"
                                              />
                            <Border Grid.ColumnSpan="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    BorderBrush="White"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="4">
                                <Border.OpacityMask>
                                    <MultiBinding Converter="{StaticResource BorderGapMaskConverter}"
                                                  ConverterParameter="7">
                                        <Binding Path="ActualWidth"
                                                 ElementName="Header" />
                                        <Binding Path="ActualWidth"
                                                 RelativeSource="{RelativeSource Self}" />
                                        <Binding Path="ActualHeight"
                                                 RelativeSource="{RelativeSource Self}" />
                                    </MultiBinding>
                                </Border.OpacityMask>
                                <Border BorderBrush="{TemplateBinding BorderBrush}"
                                        BorderThickness="{TemplateBinding BorderThickness}"
                                        CornerRadius="3">
                                    <Border BorderBrush="White"
                                            BorderThickness="{TemplateBinding BorderThickness}"
                                            CornerRadius="2" />
                                </Border>
                            </Border>
                            
                            <Border x:Name="Header"
                                    Grid.Column="1"
                                    Grid.Row="0"
                                    Grid.RowSpan="2"
                                    Padding="3,1,3,0">
                                <StackPanel Orientation="Horizontal">
                                    <CheckBox x:Name="toto"
                                              VerticalAlignment="Center"
                                              Width="20" />
                                    <TextBlock Text="{TemplateBinding Header}" />
                                </StackPanel>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    je dirais meme que c'est encore plus propre !!!! eheheh

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Citation Envoyé par ikeas Voir le message
    je dirais meme que c'est encore plus propre !!!! eheheh
    Non, il vaut mieux passer par un Custom Control car comme ca, il a la possibilité de le templatisé encore s'il le souhaite

  12. #12
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Par défaut
    oui c'est vrai thomas
    mais ceci etant il peut aussi utiliser ma solution avec un custom control

  13. #13
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Citation Envoyé par ikeas Voir le message
    oui c'est vrai thomas
    mais ceci etant il peut aussi utiliser ma solution avec un custom control
    Bien vu !
    J'ai intégré ta petite modif qui fait que maintenant je n'ai plus à gérer l'état du contenu en fonction de la coche : tout est fait dans mon CustomControl et c'est nickel comme ça.

    Merci beaucoup !

  14. #14
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Question subsidiare :

    J'aurai besoin d'utiliser mon "GroupBox cochable" dans le cas un peu particulier où le contenu doit être activé si la CheckBox est décochée

    Du coup, plutôt que de me créer un second CustomControl à cet effet, j'avais pensé compléter mon précédent CustomControl avec :
    - un IValueConverter en propriété de mon CustomControl que je pourrai assigner avec un converter permettant de renvoyer la valeur opposée au booléen qu'on lui passe en paramètre
    - une propriété IsCheckedConverted qui correspondrait à la valeur convertie de la propriété IsChecked

    J'ai donc modifié ma classe comme ceci :
    Code c# : 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
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
     
    using System.Windows.Controls;
    using System.Windows;
    using System.Windows.Data;
     
    namespace Utils
    {
        /// <summary>
        /// Class representing a GroupBox with a CheckBox in its header.
        /// </summary>
        public class CheckableGroupBox : GroupBox
        {
            static CheckableGroupBox()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckableGroupBox), new FrameworkPropertyMetadata(typeof(CheckableGroupBox)));
            }
     
     
     
     
            #region Dependency properties
     
            public static DependencyProperty IsCheckedProperty = DependencyProperty.Register(
               "IsChecked", typeof(bool), typeof(CheckableGroupBox));
     
            public static DependencyProperty IsCheckedConvertedProperty = DependencyProperty.Register(
               "IsCheckedConverted", typeof(bool), typeof(CheckableGroupBox));
     
            public static DependencyProperty StateConverterProperty = DependencyProperty.Register(
               "StateConverter", typeof(IValueConverter), typeof(CheckableGroupBox));
     
            #endregion
     
     
     
     
            #region Properties
     
            public bool IsChecked
            {
                get { return (bool)GetValue(IsCheckedProperty); }
                set 
                {
                    SetValue(IsCheckedProperty, value);
     
                    if (StateConverter != null)
                    {
                        IsCheckedConverted = (bool)StateConverter.Convert(value, typeof(bool), null, null);
                    }
                    else
                    {
                        IsCheckedConverted = value;
                    }
                }
            }
     
            private bool IsCheckedConverted
            {
                get { return (bool)GetValue(IsCheckedConvertedProperty); }
                set { SetValue(IsCheckedConvertedProperty, value); }
            }
     
            public IValueConverter StateConverter
            {
                get { return (IValueConverter)GetValue(StateConverterProperty); }
                set 
                {
                    SetValue(StateConverterProperty, value);
     
                    if (StateConverter != null)
                    {
                        IsCheckedConverted = (bool)StateConverter.Convert(IsChecked, typeof(bool), null, null);
                    }
                    else
                    {
                        IsCheckedConverted = IsChecked;
                    }
                }
            }
     
            #endregion Properties
        }
    }

    Et mon template comme ceci :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
                            <ContentPresenter Margin="{TemplateBinding Padding}"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                              Grid.Column="1"
                                              Grid.ColumnSpan="2"
                                              Grid.Row="2"
                                              IsEnabled="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type utils:CheckableGroupBox}}, Path=IsCheckedConverted, Mode=TwoWay}" />

    Malheureusement, ma propriété IsCheckedConverted n'est jamais affectée (même après avoir cliqué sur la CheckBox de mon GroupBox).
    Remarque : on ne rentre d'ailleurs jamais dans la méthode set de ma propriété IsChecked : normal ?...

    Est-ce que vous voyez ce qui ne va pas ?
    Ou est-ce que vous avez une meilleure solution ?

    Merci d'avance !

  15. #15
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    [EDIT]
    En fait, mon problème est que ma propriété IsCheckedConverted n'est pas directement initialisée avec la valeur opposée de la propriété IsChecked.

    Si je rend ma propriété IsCheckedConverted publique et que je l'initialise à la mano alors tout fonctionne bien...

    Du coup, faut que je trouve comment affecter IsCheckedConverted avec la valeur convertie de IsChecked.

  16. #16
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Bon j'ai réussi à bidouiller un truc en rajoutant une DependencyProperty IsContentEnabledWhenChecked à ma CheckableGroupBox :
    - si cette DP vaut True, alors la propriété IsEnabled du ContentPresenter est affectée avec la valeur de la DP IsChecked
    - si cette DP vaut False, alors la propriété IsEnabled du ContentPresenter est affectée avec le contraire de la valeur de la DP IsChecked

    Du coup le Style est un peu plus goret, mais au moins ça marche bien.
    Voici le code :
    Code xml : 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
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
     
    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:utils="clr-namespace:Utils"
                        xmlns:conv="clr-namespace:Utils.Converters">
     
        <BorderGapMaskConverter x:Key="BorderGapMaskConverter" />
     
     
        <!--Style for CheckableGroupBox.-->
        <Style TargetType="{x:Type utils:CheckableGroupBox}">
            <Setter Property="BorderBrush"
                    Value="CadetBlue" />
            <Setter Property="BorderThickness"
                    Value="1" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type utils:CheckableGroupBox}">
                        <Grid SnapsToDevicePixels="true">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                                <RowDefinition Height="6" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="6" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="6" />
                            </Grid.ColumnDefinitions>
                            <Border Grid.Column="0"
                                    Grid.ColumnSpan="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="Transparent"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="4" />
                            <ContentPresenter x:Name="mainContentPresenter"
                                              Margin="{TemplateBinding Padding}"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                              Grid.Column="1"
                                              Grid.ColumnSpan="2"
                                              Grid.Row="2">
                                <!--The value of the ContentPresenter's IsEnabled property depends on the values of the CheckableGroupBox's 
                                    IsChecked and IsContentEnabledWhenChecked properties.-->
                                <ContentPresenter.Style>
                                    <Style TargetType="ContentPresenter">
                                        <Style.Resources>
                                            <conv:BoolToOppositeBoolConverter_C x:Key="boolToOppositeBoolConverter2" />
                                        </Style.Resources>
                                        <Style.Triggers>
                                            <!--If the value of the CheckableGroupBox's IsContentEnabledWhenChecked property is True, 
                                                then the value of the ContentPresenter's IsEnabled property is set with the value of the
                                                CheckableGroupBox's IsChecked property.-->
                                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type utils:CheckableGroupBox}}, Path=IsContentEnabledWhenChecked}"
                                                         Value="True">
                                                <Setter Property="IsEnabled"
                                                        Value="{Binding ElementName=cbGroupBox, Path=IsChecked}" />
                                            </DataTrigger>
     
                                            <!--If the value of the CheckableGroupBox's IsContentEnabledWhenChecked property is False, 
                                                then the value of the ContentPresenter's IsEnabled property is set with the opposite 
                                                of the value of the CheckableGroupBox's IsChecked property.-->
                                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type utils:CheckableGroupBox}}, Path=IsContentEnabledWhenChecked}"
                                                         Value="False">
                                                <Setter Property="IsEnabled"
                                                        Value="{Binding ElementName=cbGroupBox, Path=IsChecked, Converter={StaticResource boolToOppositeBoolConverter2}}" />
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </ContentPresenter.Style>
                            </ContentPresenter>
                            <Border Grid.ColumnSpan="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    BorderBrush="White"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="4">
                                <Border.OpacityMask>
                                    <MultiBinding Converter="{StaticResource BorderGapMaskConverter}"
                                                  ConverterParameter="7">
                                        <Binding Path="ActualWidth"
                                                 ElementName="Header" />
                                        <Binding Path="ActualWidth"
                                                 RelativeSource="{RelativeSource Self}" />
                                        <Binding Path="ActualHeight"
                                                 RelativeSource="{RelativeSource Self}" />
                                    </MultiBinding>
                                </Border.OpacityMask>
                                <Border BorderBrush="{TemplateBinding BorderBrush}"
                                        BorderThickness="{TemplateBinding BorderThickness}"
                                        CornerRadius="3">
                                    <Border BorderBrush="White"
                                            BorderThickness="{TemplateBinding BorderThickness}"
                                            CornerRadius="2" />
                                </Border>
                            </Border>
                            <Border x:Name="Header"
                                    Grid.Column="1"
                                    Grid.Row="0"
                                    Grid.RowSpan="2"
                                    Padding="3,1,3,0">
                                <StackPanel Orientation="Horizontal">
                                    <CheckBox x:Name="cbGroupBox"
                                              IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type utils:CheckableGroupBox}}, Path=IsChecked, Mode=TwoWay}"
                                              VerticalAlignment="Center"
                                              Width="20" />
                                    <TextBlock Text="{TemplateBinding Header}" />
                                </StackPanel>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>        
        </Style>
    </ResourceDictionary>

    Code c# : 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
     
    using System.Windows.Controls;
    using System.Windows;
     
    namespace Utils
    {
        /// <summary>
        /// Class representing a GroupBox with a CheckBox in its header.
        /// </summary>
        public class CheckableGroupBox : GroupBox
        {
            static CheckableGroupBox()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckableGroupBox), new FrameworkPropertyMetadata(typeof(CheckableGroupBox)));
            }
     
     
     
     
            #region Dependency properties
     
            public static DependencyProperty IsCheckedProperty = DependencyProperty.Register(
               "IsChecked", typeof(bool), typeof(CheckableGroupBox));
     
            public static DependencyProperty IsContentEnabledWhenCheckedProperty = DependencyProperty.Register(
               "IsContentEnabledWhenChecked", typeof(bool), typeof(CheckableGroupBox), new PropertyMetadata(true));
     
            #endregion
     
     
     
     
            #region Properties
     
            public bool IsChecked
            {
                get { return (bool)GetValue(IsCheckedProperty); }
                set
                {
                    SetValue(IsCheckedProperty, value);
                }
            }
     
            public bool IsContentEnabledWhenChecked
            {
                get { return (bool)GetValue(IsContentEnabledWhenCheckedProperty); }
                set { SetValue(IsContentEnabledWhenCheckedProperty, value); }
            }
     
            #endregion Properties
        }
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment créer une CheckBox dans un module Access
    Par schnee dans le forum Access
    Réponses: 3
    Dernier message: 06/03/2014, 23h20
  2. Réponses: 7
    Dernier message: 28/03/2013, 17h13
  3. Réponses: 3
    Dernier message: 23/04/2009, 01h56
  4. Réponses: 4
    Dernier message: 22/05/2007, 16h45
  5. [2.0] Mettre une Checkbox dans le header d'une colonne d'une DatagridView
    Par aurelien.tournier dans le forum Windows Forms
    Réponses: 5
    Dernier message: 23/01/2007, 11h27

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