kurakura88
kurakura88

Reputation: 2305

Clearing other ListView Selection

How do I clear the selection in other ListView properly? For example I have 4 list views stacked, and if I have a selection in listView1, then I select a new item in listView2, I want the selection in listView1 to be gone and the item in listview2 is selected properly. Note: the list view is single selection.

<StackPanel>
   <ListView x:Name="listView1" />
   <ListView x:Name="listView2" />
   <ListView x:Name="listView3" />
   <ListView x:Name="listView4" />
</StackPanel>

I first tried:

<StackPanel>
   <ListView x:Name="listView1" SelectionChanged="selectionchanged1" />
   <ListView x:Name="listView2" SelectionChanged="selectionchanged2" />
   <ListView x:Name="listView3" SelectionChanged="selectionchanged3" />
   <ListView x:Name="listView4" SelectionChanged="selectionchanged4" />
</StackPanel>

code behind:

private void selectionChanged1(object sender, SelectionChangedEventArgs e)
{
    listView2.SelectedItem = null;
    listView3.SelectedItem = null;
    listView4.SelectedItem = null;
}
private void selectionChanged2(object sender, SelectionChangedEventArgs e)
{
    listView1.SelectedItem = null;
    listView3.SelectedItem = null;
    listView4.SelectedItem = null;
}
...

The problem I am having is that after having a selection in listView1 and click an item in listView2, the selection in listView1 is cleared, but the item in listView2 is not selected.

The reason is because there are (at least) 2 events fired:

  1. selectionchanged2 fired, claring selections in listview 1,3,4
  2. because I am clearing selection in listview1, selectionchanged1 is also fired, which clears selections in listview 2,3,4
  3. I think selectionchanged2 is fired again.
  4. Therefore I ended up with no selection in any list.

Do you have better suggestion?

Upvotes: 0

Views: 480

Answers (4)

Abdul Mateen Mohammed
Abdul Mateen Mohammed

Reputation: 1894

When you set a ListView's SelectedItem to null the SelectionChanged event will fire again because a ListView's SelectedItem was changed, so you can use a flag to skip the second SelectionChanged even call.

Check the below code snippet. I Hope it will be of help to you.

The XAML

<Window x:Class="ListView.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListView"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel x:Name="MyStackPanel">
            <ListView x:Name="listView1" SelectionChanged="listView1_SelectionChanged" SelectionMode="Single">
                <ListViewItem>Item 1</ListViewItem>
                <ListViewItem>Item 2</ListViewItem>
            </ListView>
            <ListView x:Name="listView2" SelectionChanged="listView1_SelectionChanged" SelectionMode="Single">
                <ListViewItem>Item 3</ListViewItem>
                <ListViewItem>Item 4</ListViewItem>
            </ListView>
            <ListView x:Name="listView3" SelectionChanged="listView1_SelectionChanged" SelectionMode="Single">
                <ListViewItem>Item 5</ListViewItem>
                <ListViewItem>Item 6</ListViewItem>
            </ListView>
            <ListView x:Name="listView4" SelectionChanged="listView1_SelectionChanged" SelectionMode="Single">
                <ListViewItem>Item 7</ListViewItem>
                <ListViewItem>Item 8</ListViewItem>
            </ListView>
        </StackPanel>
    </Grid>
</Window>

The Code-behind

namespace ListView
{
    using System.Windows;
    using System.Windows.Controls;

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private bool skipSelectionChanged;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void listView1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (skipSelectionChanged)
            {
                skipSelectionChanged = false;

                return;
            }

            var listView = sender as ListView;

            if (listView != null)
            {
                var name = listView.Name;
                for (int i = 0; i < MyStackPanel.Children.Count; i++)
                {
                    var child = MyStackPanel.Children[i] as ListView;
                    if (child.Name != name && child.SelectedItem != null)
                    {
                        skipSelectionChanged = true;
                        child.SelectedItem = null;
                    }
                }
            }
        }
    }
}

Upvotes: 2

Romasz
Romasz

Reputation: 29792

I think you may try to use this SelectionChanged event for all your ListViews:

private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count != 0)
    {
        if (listView1 != sender as ListView) listView1.SelectedItem = null;
        if (listView2 != sender as ListView) listView2.SelectedItem = null;
        if (listView3 != sender as ListView) listView3.SelectedItem = null;
        if (listView4 != sender as ListView) listView4.SelectedItem = null;
    }
}

It just check if there is something new set in ListView, if so, then clear all other ListViews.

Upvotes: 1

Saurabh Harwande
Saurabh Harwande

Reputation: 171

You can add a null check before clearing other fields like

For listView1:

private void selectionChanged1(object sender, SelectionChangedEventArgs e)
{
    if(listView1.SelectedItem == null)
    {
        listView2.SelectedItem = null;
        listView3.SelectedItem = null;
        listView4.SelectedItem = null;
    }
}

Similarly you can change it for others.

Upvotes: 0

Keyur PATEL
Keyur PATEL

Reputation: 2329

Maybe try this: Link them all to the same handler, such as:

<StackPanel>
   <ListView x:Name="listView1" SelectionChanged="selectionchanged" />
   <ListView x:Name="listView2" SelectionChanged="selectionchanged" />
   <ListView x:Name="listView3" SelectionChanged="selectionchanged" />
   <ListView x:Name="listView4" SelectionChanged="selectionchanged" />
</StackPanel>

and then:

private void selectionChanged(object sender, SelectionChangedEventArgs e)
{
    string listViewName = ((ListView)sender).Name;
    if (listViewName == "listView1")
    {
        listView2.SelectedItem = null;
        listView3.SelectedItem = null;
        listView4.SelectedItem = null;
    }
    else if (listViewName == "listView3")
    {
        listView1.SelectedItem = null;
        listView2.SelectedItem = null;
        listView4.SelectedItem = null;
    }
    else if (listViewName == "listView4")
    {
        listView1.SelectedItem = null;
        listView2.SelectedItem = null;
        listView3.SelectedItem = null;
    }
    else if (listViewName == "listView2")
    {
        listView1.SelectedItem = null;
        listView3.SelectedItem = null;
        listView4.SelectedItem = null;
    }
}

It is messy and long (and untested), but let me know if it works.

Upvotes: 0

Related Questions