我在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方法中,我总是得到一些随机数。这有什么问题。
修改 *我不想在ViewModel中使用IsSelected标志
答案 0 :(得分:1)
对我来说,似乎您启用了ListView
UI虚拟化,因为它默认启用。这意味着,ListView
仅绘制UI上可见的项目。
以下是MSDN link
为了确定接口上的内容(例如您的选择)我恐怕您没有其他选择
或禁用UI虚拟化(不好)
或在ModelView上实现IsSelected
标志
答案 1 :(得分:1)
您可以使用行为将所选项目同步到视图模型中的集合....
您需要在项目中添加对System.Windows.Interactivity
的引用以及Xaml中的别名
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;
}
}
}
<ListView ItemsSource="{Binding ItemsList}"
DisplayMemberPath="Name"
SelectionMode="Extended">
<i:Interaction.Behaviors>
<local:MultiSelectionBehavior SelectedItems="{Binding MySelectedItems}" />
</i:Interaction.Behaviors>
</ListView>
MySelectedItems
是ViewModel中的集合
不要忘记它在ViewModel中初始化... MySelectedItems
....
private void ExcludeCurveExecuted(object param)
{
int count = MySelectedItems.Count;
}