1. Jednym ze sposobów wiązania źródło:
Musisz użyć SelectionChanged
wydarzenie. Najprostszym sposobem jest napisanie programu obsługi zdarzeń w codebehind, aby "powiązać selecteditems" z viewmodel.
//ViewModel
public ICollectionView BusinessCollection {get; set;}
public List<YourBusinessItem> SelectedObject {get; set;}
//Codebehind
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var viewmodel = (ViewModel) DataContext;
viewmodel.SelectedItems = listview.SelectedItems
.Cast<YourBusinessItem>()
.ToList();
}
To nadal wyrównuje się z projektem MVVM, ponieważ zakresy widoku i viewmodel są oddzielone. Nie masz żadnej logiki w codebehind i viewmodel jest czysty i testowalny.
2. Dwa sposób wiążący:
jeśli trzeba także zaktualizować widok, kiedy ViewModel zmiany, trzeba dołączyć do PropertyChanged
przypadku ViewModel i do CollectionChanged
przypadku wybranych pozycji. Oczywiście można to zrobić w kodzie, ale w tym przypadku chciałbym stworzyć coś bardziej wielokrotnego użytku:
//ViewModel
public ObservableCollection<YourBusinessItem> SelectedObject {get; set;}
//in codebehind:
var binder = new SelectedItemsBinder(listview, viewmodel.SelectedItems);
binder.Bind();
lub mogą tworzyć niestandardowe załączony właściwość, dzięki czemu można używać składni wiążącej w XAML:
<ListView local:ListViewExtensions.SelectedValues="{Binding SelectedItem}" .../>
public class SelectedItemsBinder
{
private ListView _listBox;
private IList _collection;
public SelectedItemsBinder(ListView listBox, IList collection)
{
_listBox = listBox;
_collection = collection;
_listBox.SelectedItems.Clear();
foreach (var item in _collection)
{
_listBox.SelectedItems.Add(item);
}
}
public void Bind()
{
_listBox.SelectionChanged += ListBox_SelectionChanged;
if (_collection is INotifyCollectionChanged)
{
var observable = (INotifyCollectionChanged) _collection;
observable.CollectionChanged += Collection_CollectionChanged;
}
}
public void UnBind()
{
if (_listBox != null)
_listBox.SelectionChanged -= ListBox_SelectionChanged;
if (_collection != null && _collection is INotifyCollectionChanged)
{
var observable = (INotifyCollectionChanged) _collection;
observable.CollectionChanged -= Collection_CollectionChanged;
}
}
private void Collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
foreach (var item in e.NewItems ?? new object[0])
{
if (!_listBox.SelectedItems.Contains(item))
_listBox.SelectedItems.Add(item);
}
foreach (var item in e.OldItems ?? new object[0])
{
_listBox.SelectedItems.Remove(item);
}
}
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach (var item in e.AddedItems ?? new object[0])
{
if (!_collection.Contains(item))
_collection.Add(item);
}
foreach (var item in e.RemovedItems ?? new object[0])
{
_collection.Remove(item);
}
}
}
Dołączone nieruchomość realizacja
public class ListBoxExtensions
{
private static SelectedItemsBinder GetSelectedValueBinder(DependencyObject obj)
{
return (SelectedItemsBinder)obj.GetValue(SelectedValueBinderProperty);
}
private static void SetSelectedValueBinder(DependencyObject obj, SelectedItemsBinder items)
{
obj.SetValue(SelectedValueBinderProperty, items);
}
private static readonly DependencyProperty SelectedValueBinderProperty = DependencyProperty.RegisterAttached("SelectedValueBinder", typeof(SelectedItemsBinder), typeof(ListBoxExtensions));
public static readonly DependencyProperty SelectedValuesProperty = DependencyProperty.RegisterAttached("SelectedValues", typeof(IList), typeof(ListBoxExtensions),
new FrameworkPropertyMetadata(null, OnSelectedValuesChanged));
private static void OnSelectedValuesChanged(DependencyObject o, DependencyPropertyChangedEventArgs value)
{
var oldBinder = GetSelectedValueBinder(o);
if (oldBinder != null)
oldBinder.UnBind();
SetSelectedValueBinder(o, new SelectedItemsBinder((ListBox)o, (IList)value.NewValue));
GetSelectedValueBinder(o).Bind();
}
public static void SetSelectedValues(Selector elementName, IEnumerable value)
{
elementName.SetValue(SelectedValuesProperty, value);
}
public static IEnumerable GetSelectedValues(Selector elementName)
{
return (IEnumerable)elementName.GetValue(SelectedValuesProperty);
}
}
Wielkie dzięki, bardzo mi to pomogło :) –
Dzięki za kod. Powinieneś również obsługiwać resetowanie kolekcji w metodzie Collection_CollectionChanged. –