0
votes

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?

4

4 Answers

2
votes

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;
                    }
                }
            }
        }
    }
}
1
votes

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.

0
votes

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.

0
votes

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.