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 :

Sélectionner un ListViewItem lors d'un clic sur un élément contenu dans son ItemTemplate


Sujet :

Windows Presentation Foundation

  1. #1
    Modérateur
    Avatar de Sankasssss
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 842
    Points : 4 232
    Points
    4 232
    Par défaut Sélectionner un ListViewItem lors d'un clic sur un élément contenu dans son ItemTemplate
    Bonjour,

    J'ai un ListView dont je défini l'ItemTemplate avec des TextBlock, DecimalUpDown et autres.
    Lorsque l'on clique sur un élément non éditable comme le TextBlock, pas de soucis il sélectionne bien le ListViewItem mais lorsque l'on clique sur un élément éditable et qu'il prend le focus, cela ne sélectionne pas en même temps le ListViewItem dans lequel il est contenu.
    Si on avait précédemment sélectionné un autre ListViewItem, celui-ci reste sélectionné alors que l'on est occupé à en éditer un autre.

    Voici le code du ListView:

    Code xaml : 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
     <ListView Name="ListViewStoreInfos" Background="Transparent" BorderBrush="Transparent" Margin="0,-4,0,-2" 
                                      SelectedItem="{Binding StoreInfo}" ItemsSource="{Binding Contract.StoreInfos}" 
                                      KeyboardNavigation.TabNavigation="Cycle" >
                                <!-- WPF: How To Tab Between Items In a ListBox -->
                                <!-- https://social.technet.microsoft.com/wiki/contents/articles/25152.wpf-how-to-tab-between-items-in-a-listbox.aspx -->
                                <ListView.ItemContainerStyle>
                                    <Style TargetType="ListViewItem">
                                        <Setter Property="IsTabStop" Value="False"/>
                                    </Style>
                                </ListView.ItemContainerStyle>
                                <ListView.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Orientation="Horizontal"  ></StackPanel>
                                    </ItemsPanelTemplate>
                                </ListView.ItemsPanel>
     
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <Grid DockPanel.Dock="Left" VerticalAlignment="Top">
                                            <Grid.Resources>
                                                <Style TargetType="RowDefinition">
                                                    <Setter Property="Height" Value="22" />
                                                </Style>
                                                <Style TargetType="TextBlock">
                                                    <Setter Property="VerticalAlignment" Value="Center"/>
                                                </Style>
                                                <Style TargetType="DatePicker">
                                                    <Setter Property="MaxWidth" Value="100"/>
                                                    <Setter Property="Margin" Value="0,0,0,2"/>
                                                </Style>
                                            </Grid.Resources>
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height="20" />
                                                <RowDefinition Height="20"/>
                                                <RowDefinition Height="27" />
                                                <RowDefinition Height="27" />
                                                <RowDefinition />
                                                <RowDefinition />
                                                <RowDefinition />
                                                <RowDefinition />
                                                <RowDefinition />
                                            </Grid.RowDefinitions>
                                            <TextBlock Text="{Binding Store.Code}" FontWeight="Bold" Grid.Row="0" />
                                            <TextBlock Text="{Binding Store.Name}" FontWeight="Bold" Grid.Row="1" />
                                            <DatePicker SelectedDate="{Binding Start}" Grid.Row="2" />
                                            <DatePicker SelectedDate="{Binding End}" Grid.Row="3" />
                                            <xceed:DecimalUpDown Value="{Binding Margin}" Grid.Row="4" Minimum="0" Maximum="99.99"/>
                                            <TextBlock Text="{Binding MarginSupplier}" Grid.Row="5" />
                                            <xceed:IntegerUpDown Value="{Binding Minutes}" Grid.Row="6" Margin="0,0,0,2"  Minimum="0"  />
                                            <xceed:DecimalUpDown Value="{Binding SummerMeter}" Grid.Row="7" Margin="0,0,0,2"  Minimum="0" Maximum="99.99" />
                                            <xceed:DecimalUpDown Value="{Binding WinterMeter}" Grid.Row="8" Margin="0,0,0,2"  Minimum="0" Maximum="99.99"/>
                                            <Button Name="ButtonDeleteStore" HorizontalAlignment="Right" Background="Transparent" BorderBrush="Transparent" Click="ButtonRemoveStore_Click" Grid.RowSpan="2" VerticalAlignment="Top" >
                                                <Button.ToolTip>
                                                    <WrapPanel>
                                                        <TextBlock Name="TextBlockToolTipDeleteStore" Text="Delete store infos " />
                                                        <TextBlock Text="{Binding Store.DisplayCodeName}" />
                                                    </WrapPanel>
                                                </Button.ToolTip>
                                                <Image Height="15" Source="/Ressources/Close.png" Margin="2"/>
                                            </Button>
                                        </Grid>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>

    Vous vous doutez donc de la question : Comment faire en sorte que lorsque l'on clic sur un élément éditable ça sélectionne en même temps le ListViewItem parent pour rester cohérent.

    On peut voir ici que c'est la date du premier item qui a le focus mais que c'est le deuxième item est sélectionné :
    Nom : ListView.png
Affichages : 278
Taille : 14,5 Ko

    Merci d'avance pour votre aide.

  2. #2
    Modérateur
    Avatar de Sankasssss
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 842
    Points : 4 232
    Points
    4 232
    Par défaut
    J'ai finalement trouvé une alternative en forçant le SelectedItem du ListView en code-behind lorsqu'un élément prend le focus :
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            <DatePicker SelectedDate="{Binding Start}" Grid.Row="2" Loaded="DatePicker_Loaded"  />
            <DatePicker SelectedDate="{Binding End}" Grid.Row="3" Loaded="DatePicker_Loaded"/>
            <xceed:DecimalUpDown Value="{Binding Margin}" Grid.Row="4" Minimum="0" Maximum="99.99" GotFocus="DecimalUpDown_GotFocus"/>
            <TextBlock Text="{Binding MarginSupplier}" Grid.Row="5" />
            <xceed:IntegerUpDown Value="{Binding Minutes}" Grid.Row="6" Margin="0,0,0,2"  Minimum="0" GotFocus="IntegerUpDown_GotFocus" />
            <xceed:DecimalUpDown Value="{Binding SummerMeter}" Grid.Row="7" Margin="0,0,0,2"  Minimum="0" Maximum="99.99"  GotFocus="DecimalUpDown_GotFocus"/>
            <xceed:DecimalUpDown Value="{Binding WinterMeter}" Grid.Row="8" Margin="0,0,0,2"  Minimum="0" Maximum="99.99" GotFocus="DecimalUpDown_GotFocus"/>
    Code vb.net : 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
     
        Private Sub DatePicker_GotFocus(sender As Object, e As RoutedEventArgs)
            StoreInfo = CType(CType(sender, DatePicker).DataContext, StoreInfoBll)
            e.Handled = False
        End Sub
     
        Private Sub DatePicker_Loaded(sender As Object, e As RoutedEventArgs)
            CType(sender, DatePicker).AddHandler(DatePicker.GotFocusEvent, New RoutedEventHandler(AddressOf DatePicker_GotFocus), True)
        End Sub
     
        Private Sub DecimalUpDown_GotFocus(sender As Object, e As RoutedEventArgs)
            StoreInfo = CType(CType(sender, Xceed.Wpf.Toolkit.DecimalUpDown).DataContext, StoreInfoBll)
        End Sub
     
        Private Sub IntegerUpDown_GotFocus(sender As Object, e As RoutedEventArgs)
            StoreInfo = CType(CType(sender, Xceed.Wpf.Toolkit.IntegerUpDown).DataContext, StoreInfoBll)
        End Sub

    Petite subtilité pour le DatePicker qui par défaut ne lève pas l’événement GotFocus, il faut le forcer à lever l’événement via DatePicker_Loaded.

    Bonne journée,

  3. #3
    Membre expérimenté
    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
    Points : 1 313
    Points
    1 313
    Par défaut
    en version simple y a ça

    que j'utilise régulièrement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <Style.Triggers>
      <Trigger Property="IsKeyboardFocusWithin" Value="True">
        <Setter Property="IsSelected" Value="True"/>
      </Trigger>
    </Style.Triggers>
    sinon plus compliqué mais sympa
    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
      public class AutoSelectWhenAnyChildGetsFocus
        {
            public static readonly DependencyProperty EnabledProperty = DependencyProperty.RegisterAttached(
                "Enabled",
                typeof(bool),
                typeof(AutoSelectWhenAnyChildGetsFocus),
                new UIPropertyMetadata(false, Enabled_Changed));
     
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Valider les arguments de méthodes publiques", MessageId = "0")]
            public static bool GetEnabled(DependencyObject obj) { return (bool)obj.GetValue(EnabledProperty); }
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Valider les arguments de méthodes publiques", MessageId = "0")]
            public static void SetEnabled(DependencyObject obj, bool value) { obj.SetValue(EnabledProperty, value); }
     
            private static void Enabled_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
            {
                var attachEvents = (bool)e.NewValue;
                var targetUiElement = (UIElement)sender;
     
                if (attachEvents)
                {
                    targetUiElement.IsKeyboardFocusWithinChanged += TargetUiElement_IsKeyboardFocusWithinChanged;
                }
                else
                {
                    targetUiElement.IsKeyboardFocusWithinChanged -= TargetUiElement_IsKeyboardFocusWithinChanged;
                }
     
            }
     
            static void TargetUiElement_IsKeyboardFocusWithinChanged(object sender, DependencyPropertyChangedEventArgs e)
            {
                var targetUiElement = (UIElement)sender;
     
                if ((targetUiElement.IsKeyboardFocusWithin) && (!Selector.GetIsSelected(targetUiElement)))
                {
                    bool multiSelect = (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)
                                        || Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl));
     
                    Selector parent = targetUiElement.FindParent<Selector>();
                    UIElement selectableUIElement = targetUiElement;
                    if (parent != null)
                    {
                        if (parent is ListBox)
                        {
                            multiSelect &= ((ListBox)parent).SelectionMode != SelectionMode.Single;
                            if (!(targetUiElement is ListBoxItem))
                                selectableUIElement = targetUiElement.FindParent<ListBoxItem>();
                        }
                    }
     
                    if ((!multiSelect) && (parent != null))
                        parent.SelectedIndex = -1;
                    else if (multiSelect && targetUiElement.IsKeyboardFocused)
                        return;
     
                    if (selectableUIElement != null)
                    {
                        if (selectableUIElement is ListBoxItem)
                            ((ListBoxItem)selectableUIElement).IsSelected = true;
                        else
                            Selector.SetIsSelected(selectableUIElement, true);
                    }
                }
            }
        }
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     <Style TargetType="{x:Type ListViewItem}"
               BasedOn="{StaticResource {x:Type ListViewItem}}">    
            <Setter Property="conv:AutoSelectWhenAnyChildGetsFocus.Enabled"
                    Value="True" />
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  4. #4
    Modérateur
    Avatar de Sankasssss
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 842
    Points : 4 232
    Points
    4 232
    Par défaut
    Merci pour ces deux exemples. Je testerai ça à l'occasion.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 08/02/2010, 23h10
  2. [JFrame] lancer une méthode lors d'un clic sur la croix rouge
    Par Mushu74 dans le forum Agents de placement/Fenêtres
    Réponses: 5
    Dernier message: 17/06/2008, 15h55
  3. Récupérer l'index lors d'un clic sur menustrip
    Par GriffinK dans le forum VB.NET
    Réponses: 5
    Dernier message: 15/04/2008, 14h54
  4. Ouvrir 4 états lors d'un clic sur un bouton
    Par Seb33300 dans le forum WebDev
    Réponses: 8
    Dernier message: 28/01/2008, 15h53
  5. Réponses: 3
    Dernier message: 23/10/2007, 13h35

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