tags:

views:

93

answers:

2

I have an action Edit in my WPF application, which is bound to items in a ListView control, i.e. it is executed when an item is double clicked or the Edit button in the toolbar is clicked. This action in turn displays a modal window with the editing stuff.

Now when I select multiple items in the list, click Edit, the items stay selected in the background, also, when I close the dialog, they are still selected in the sence that their background is blue. However, they seem to be not selected in the sence that the Edit button is disabled in the toolbar (the Edit action's CanExecute method simply checks FileList.SelectedIndex != -1. What's more, the "selected" items won't get deselected when I click some other list item - they only get deselected when I explicitly click on them one by one - it's as if the blue background is stuck on them.

My code does not use any fancy ListView styles or what not, so what could be causing this ? I can post my code upon request, but it is pretty much standard.

EDIT:

After cutting down my code I finally found what's causing this issue. After showing the dialog, I edit the items in the data bound collection, so that the ListView would get updated (i.e. replace the bound objects to new objects). The question is, why is this causing a problem and how should I resolve it ?

A: 

What do you have ListView.SelectionMode set to? It sounds like it is set to Multiple (clicking an item extends the selection), while you might want to set it to Extended (selection is extended when clicking an item and pressing Control or Shift) instead.

I'm not sure what to say about the Edit command problem, though. Maybe there is an odd behavior with SelectedIndex and multiple selection - possibly check the count of the objects in the ListView.SelectedItems collection instead?

Andy
SelectionMode is Extented - it works as expected as long as I don't display any modal dialogs. And SelectedIndex is equal to the first selected item when multiple items are selected, since the Edit button visibility correctly corresponds to selecting items (even a few of them).
Saulius
A: 

Something in your code must be causing this issues. Below is a sample which behaves as expected.

XAML:

<Window x:Class="TestDemo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">

    <Window.Resources>
        <RoutedUICommand x:Key="EditItemsCommand" Text="Edit Items" />
    </Window.Resources>

    <Window.CommandBindings>
        <CommandBinding 
            Command="{StaticResource EditItemsCommand}" 
            CanExecute="EditItems_CanExecute" 
            Executed="EditItems_Executed" />
    </Window.CommandBindings>

    <StackPanel>
        <Button Name="_editButton" Content="Edit" Command="{StaticResource EditItemsCommand}" />
        <Button Content="Unselect all" Click="OnUnselectAll" />
        <ListView 
            Name="_listView"
            ItemsSource="{Binding Path=Items}" 
            SelectionMode="Extended"
            MouseDoubleClick="OnListViewMouseDoubleClick">
        </ListView>
    </StackPanel>
</Window>

Code behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Input;

namespace TestDemo
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = this;
        }

        public IEnumerable<string> Items
        {
            get 
            {
                for (int i = 0; i < 10; i++) { yield return i.ToString(); }
            }
        }

        private void EditItems_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _listView != null && _listView.SelectedItems.Count > 0;
        }

        private void EditItems_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            EditWindow editWindow = new EditWindow();
            editWindow.EditItems = _listView.SelectedItems.Cast<string>();
            editWindow.ShowDialog();
        }

        private void OnListViewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            _editButton.Command.Execute(null);
        }

        private void OnUnselectAll(object sender, RoutedEventArgs e)
        {
            _listView.SelectedItem = null;
        }
    }
}

XAML:

<Window x:Class="TestDemo.EditWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="EditWindow">
    <ListBox ItemsSource="{Binding Path=EditItems}" />
</Window>

Code behind:

using System;
using System.Collections.Generic;
using System.Windows;

namespace TestDemo
{
    public partial class EditWindow : Window
    {
        public EditWindow()
        {
            InitializeComponent();

            DataContext = this;
        }

        public IEnumerable<string> EditItems { get; set; }
    }
}
Wallstreet Programmer
You're right, see my edit.
Saulius