MultiSelection не работает в ListView - PullRequest
0 голосов
/ 31 января 2012

У меня проблема в ListView MultiSelection.

Вот мой код:

   private ICommand _excludeCurveCommand;


    public ICommand ExcludeCurveCommand
    {
        get
        {
            if (_excludeCurveCommand == null)
                _excludeCurveCommand = new DelegateCommand<object>(param => this.ExcludeCurveExecuted(param));

            return _excludeCurveCommand;
        }
    }

    /// <summary>
    /// Executed event for ContextMenu --> Remove click
    /// </summary>
    /// <param name="param">param is FolderItemViewModel bound as CommandParameter</param>
    private void ExcludeCurveExecuted(object param)
    {

        ICollection<object> curves = param as ICollection<object>;
        int count =  curves.Count;
    }



 < Button Content="Exclude" Command="{Binding ExcludeCurveCommand}" CommandParameter="{Binding SelectedItems,ElementName=lstView}" .../>

< ListView Name="lstView"  ItemsSource="{Binding MyList}" SelectionMode="Extended" ..../>

Здесь я использовал shift и выбрал из первых четырех пунктов. Но в методе ExcludeCurveExecuted я всегда получаю случайные значения. В чем проблема в этом.

EDIT: * Я не хочу идти с флагом IsSelected в ViewModel

Ответы [ 2 ]

1 голос
/ 31 января 2012

Вы можете использовать Поведение для синхронизации выбранных элементов с коллекцией в вашей модели просмотра ....

Вы можете добавить ссылку на System.Windows.Interactivity в свой проект и псевдоним к нему в своем Xaml

Beahvior

public class MultiSelectionBehavior : Behavior<ListView>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            if (SelectedItems != null)
            {
                AssociatedObject.SelectedItems.Clear();
                foreach (var item in SelectedItems)
                {
                    AssociatedObject.SelectedItems.Add(item);
                }
            }
        }

public IList SelectedItems
{
    get { return (IList)GetValue(SelectedItemsProperty); }
    set { SetValue(SelectedItemsProperty, value); }
}

public static readonly DependencyProperty SelectedItemsProperty =
    DependencyProperty.Register("SelectedItems", typeof(IList), typeof(MultiSelectionBehavior), new UIPropertyMetadata(null, SelectedItemsChanged));

private static void SelectedItemsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    var behavior = o as MultiSelectionBehavior;
    if (behavior == null)
        return;

    var oldValue = e.OldValue as INotifyCollectionChanged;
    var newValue = e.NewValue as INotifyCollectionChanged;

    if (oldValue != null)
    {
        oldValue.CollectionChanged -= behavior.SourceCollectionChanged;
        behavior.AssociatedObject.SelectionChanged -= behavior.ListViewSelectionChanged;
    }
    if (newValue != null)
    {
        behavior.AssociatedObject.SelectedItems.Clear();
        foreach (var item in (IEnumerable)newValue)
        {
            behavior.AssociatedObject.SelectedItems.Add(item);
        }

        behavior.AssociatedObject.SelectionChanged += behavior.ListViewSelectionChanged;
        newValue.CollectionChanged += behavior.SourceCollectionChanged;
    }
}

private bool _isUpdatingTarget;
private bool _isUpdatingSource;

void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (_isUpdatingSource)
        return;

    try
    {
        _isUpdatingTarget = true;

        if (e.OldItems != null)
        {
            foreach (var item in e.OldItems)
            {
                AssociatedObject.SelectedItems.Remove(item);
            }
        }

        if (e.NewItems != null)
        {
            foreach (var item in e.NewItems)
            {
                AssociatedObject.SelectedItems.Add(item);
            }
        }
    }
    finally
    {
        _isUpdatingTarget = false;
    }
}

private void ListViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (_isUpdatingTarget)
        return;

    var selectedItems = this.SelectedItems;
    if (selectedItems == null)
        return;

    try
    {
        _isUpdatingSource = true;

        foreach (var item in e.RemovedItems)
        {
            selectedItems.Remove(item);
        }

        foreach (var item in e.AddedItems)
        {
            selectedItems.Add(item);
        }
    }
    finally
    {
        _isUpdatingSource = false;
    }
}

}

Xaml

    <ListView ItemsSource="{Binding ItemsList}"
             DisplayMemberPath="Name"
             SelectionMode="Extended">
        <i:Interaction.Behaviors>
            <local:MultiSelectionBehavior SelectedItems="{Binding MySelectedItems}" />
        </i:Interaction.Behaviors>
    </ListView>

MySelectedItems - это коллекция в вашей ViewModel

Не забудьте инициализировать ... MySelectedItems в вашей ViewModel ....

Ваша ViewModel

private void ExcludeCurveExecuted(object param)
{                  
    int count =  MySelectedItems.Count;
} 
1 голос
/ 31 января 2012

Мне кажется, у вас включена виртуализация пользовательского интерфейса ListView, так как она включена по умолчанию. Это означает, что ListView рисует только элементы, видимые в пользовательском интерфейсе.

Вот MSDN ссылка

Чтобы быть уверенным, что происходит в интерфейсе (например, выбор в вашем случае), боюсь, у вас нет другого выбора, кроме

  • или отключить виртуализацию пользовательского интерфейса (не хорошо)

  • или внедрить флаг IsSelected в ModelView

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...