7
votes

Empêcher ListView de perdre l'article sélectionné

Je travaille actuellement sur une liste de liste à Winform C # Et chaque fois que je clique sur un espace vide sur la liste de liste, L'élément sélectionné est perdu.


3 commentaires

Winforms ou WPF? Espace vide à droite ou en dessous? Qu'est-ce que tu veux qu'il arrive?


Dupliqué possible de interdire listview d'avoir zéro des articles sélectionnés


dans les propriétés ... Hideselection = Faux et Fullrowselect = True


6 Réponses :


2
votes

Je pensais qu'il y avait une propriété qui empêchait cela de se produire, mais je ne peux maintenant pas le trouver.

Vous pouvez essayer ceci: p>

private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListView listView = sender as ListView;
    if (listView.SelectedItems.Count == 0)
        foreach (object item in e.RemovedItems)
            listView.SelectedItems.Add(item);
}


2 commentaires

@Grammargrain - La question ne précisait pas si c'était WPF, Winforms, ASP, Silverlight ou autre chose. Je viens de répondre avec celui que j'ai ouvert dans l'IDE pour le moment. Vous devriez publier une réponse avec votre technologie d'affichage C # préférée! :-)


@Jeffery Ce n'était pas une critique. Il suffit de préciser pour un débutant pourquoi votre réponse correcte peut ne pas fonctionner pour lui.



1
votes

Ceci est beaucoup plus difficile à faire dans Winforms que dans WPF. Winforms a un événement SELECTECYINDEXCHANGED CODE> qui ne vous dit rien sur ce qui a déjà été sélectionné, plus em> il est tiré à chaque fois qu'une ligne est sélectionnée ou désélectionnée.

Donc si Une ligne est sélectionnée et vous sélectionnez une ligne différente, vous recevez deux sélectionnésExchangedexchanged code> événements: p>

  1. un après la ligne sélectionnée est désélectionné li>
  2. Un autre lorsque la nouvelle ligne est sélectionnée. LI> ol>

    Le problème est que, pendant l'événement n ° 1, la View n'a rien de sélection et que vous ne savez pas si l'événement n ° 2 arrive qui sélectionnera la deuxième ligne. P>

    Le meilleur Vous pouvez faire est d'attendre que votre application soit inactive (quelques millisecondes après que la sélection a changé), et si la liste de liste n'a toujours rien sélectionné, remettez la dernière ligne sélectionnée. P>

    private void listView1_SelectedIndexChanged(object sender, EventArgs e)
    {
        ListView lv = (ListView)sender;
        if (lv.SelectedIndices.Count == 0)
        {
            if (!this.appIdleEventScheduled)
            {
                this.appIdleEventScheduled = true;
                this.listViewToMunge = lv;
                Application.Idle += new EventHandler(Application_Idle);
            }
        }
        else
            this.lastSelectedIndex = lv.SelectedIndices[0];
    }
    
    void Application_Idle(object sender, EventArgs e)
    {
        Application.Idle -= new EventHandler(Application_Idle);
        this.appIdleEventScheduled = false;
        if (listViewToMunge.SelectedIndices.Count == 0) 
            listViewToMunge.SelectedIndices.Add(this.lastSelectedIndex);
    }
    
    private bool appIdleEventScheduled = false;
    private int lastSelectedIndex = -1;
    private ListView listViewToMunge;
    


0 commentaires

2
votes

Je l'ai accompli comme ceci: xxx

et xxx


0 commentaires

3
votes

Vous devez hériter de la classe ListView et faire un traitement de message de bas niveau

class ListViewThatKeepsSelection : ListView
{
    protected override void WndProc(ref Message m)
    {
        // Suppress mouse messages that are OUTSIDE of the items area
        if (m.Msg >= 0x201 && m.Msg <= 0x209)
        {
            Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
            var hit = this.HitTest(pos);
            switch (hit.Location)
            {
                case ListViewHitTestLocations.AboveClientArea:
                case ListViewHitTestLocations.BelowClientArea:
                case ListViewHitTestLocations.LeftOfClientArea:
                case ListViewHitTestLocations.RightOfClientArea:
                case ListViewHitTestLocations.None:
                    return;
            }
        }
        base.WndProc(ref m);
    }
}


0 commentaires

8
votes

Le contrôle ListView a une propriété Hideselection par défaut sur true . Faites-le faux et vous êtes prêt à partir ... Dans certains cas, cela suffit.


2 commentaires

Cela ne résout pas le problème posté, il n'a pas de problème d'éléments désélectionnant lorsqu'il perd la mise au point.


Correction: il est avoir un problème de désélectionnant. Les éléments sélectionnés ne sont pas mis en évidence car le contrôle perd quels éléments sont sélectionnés.



0
votes

Je sais que la question posée il y a 10 ans. Mais je fais face au même problème et j'ai trouvé une solution simple et élégante tout à l'heure et veulent sincèrement le partager.

Il y a un code (dans vb.net mais son gros problème à écrire la même chose en C #): P >

Public Class SettingsBox ' Form that contains ListView (lvScreen)

    Private nScreenTracer As Integer
    Private nSelectedScreen As Integer

    Private Sub lvScreen_ItemSelectionChanged(sender As Object,
                                              e As ListViewItemSelectionChangedEventArgs) Handles lvScreen.ItemSelectionChanged
        If e.IsSelected Then nScreenTracer = e.Item.Index
    End Sub

    Private Sub lvScreen_MouseDown(sender As Object,
                                   e As MouseEventArgs) Handles lvScreen.MouseDown
        nScreenTracer = -1
    End Sub

    Private Sub lvScreen_MouseUp(sender As Object,
                                 e As MouseEventArgs) Handles lvScreen.MouseUp
        If nScreenTracer = -1 Then
            lvScreen.SelectedIndices.Add(nSelectedScreen)
        Else
            nSelectedScreen = nScreenTracer
        End If
    End Sub

End Class


0 commentaires