Benötigen Sie die SelectedCells, die ständig mit Daten verknüpft sind oder nur wenn der Benutzer die OK/Accept-Taste drückt? Wenn Sie es nur am Ende des Prozesses, in dem sich der Benutzer befindet, benötigen, können Sie die SelectedCells beispielsweise an die CommandParameter-Eigenschaft eines Buttons binden. Die SelectedCells ist eine IList, und Sie wissen genug, um einen Cast für jeden Objekttyp durchzuführen, der tatsächlich ausgewählt ist. Die andere Option ist unordentlicher, Sie können eine angefügte Eigenschaft verwenden, um die Ereignisbehandlung aus Ihren Ansichten herauszuhalten. Diese angefügte Eigenschaft würde entweder eine ListBox oder in Ihrem Fall ein DataGrid (MultiSelector) behandeln.
public class Attach
{
public static IList GetSelectedItems(DependencyObject obj)
{
return (IList)obj.GetValue(SelectedItemsProperty);
}
public static void SetSelectedItems(DependencyObject obj, IList value)
{
obj.SetValue(SelectedItemsProperty, value);
}
/// <summary>
/// Attach this property to expose the read-only SelectedItems property of a MultiSelector for data binding.
/// </summary>
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(Attach), new UIPropertyMetadata(new List<object>() as IList, OnSelectedItemsChanged));
static SelectionChangedEventHandler GetSelectionChangedHandler(DependencyObject obj)
{
return (SelectionChangedEventHandler)obj.GetValue(SelectionChangedHandlerProperty);
}
static void SetSelectionChangedHandler(DependencyObject obj, SelectionChangedEventHandler value)
{
obj.SetValue(SelectionChangedHandlerProperty, value);
}
static readonly DependencyProperty SelectionChangedHandlerProperty =
DependencyProperty.RegisterAttached("SelectionChangedHandler", typeof(SelectionChangedEventHandler), typeof(Attach), new UIPropertyMetadata(null));
//d is MultiSelector (d as ListBox not supported)
static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
if (GetSelectionChangedHandler(d) != null)
return;
if (d is MultiSelector)//DataGrid
{
MultiSelector multiselector = d as MultiSelector;
SelectionChangedEventHandler selectionchanged = null;
foreach (var selected in GetSelectedItems(d) as IList)
multiselector.SelectedItems.Add(selected);
selectionchanged = (sender, e) =>
{
SetSelectedItems(d, multiselector.SelectedItems);
};
SetSelectionChangedHandler(d, selectionchanged);
multiselector.SelectionChanged += GetSelectionChangedHandler(d);
}
else if (d is ListBox)
{
ListBox listbox = d as ListBox;
SelectionChangedEventHandler selectionchanged = null;
selectionchanged = (sender, e) =>
{
SetSelectedItems(d, listbox.SelectedItems);
};
SetSelectionChangedHandler(d, selectionchanged);
listbox.SelectionChanged += GetSelectionChangedHandler(d);
}}}
Verwendung in XAML:
<DataGrid ItemsSource="{Binding Path=SourceList}"
myControls:Attach.SelectedItems="{Binding Path=myMvvmSelectedItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectionMode="Extended" />
T.Websters Antwort ist gut, wenn Sie .NET4 verwenden. Offenbar, wenn Sie .NET3.5 verwenden und das DataGrid aus dem WPF-Toolkit nehmen, gibt es wahrscheinlich keine einfache Antwort und Sie müssen das SelectedCellsChanged-Ereignis abfangen und manuell 'myGrid.SelectedCells' holen und es an Ihr ViewModel weitergeben . Ich weiß, es klingt lahm, aber es gibt wahrscheinlich keinen anderen Weg. – GuYsH
Ich überprüft Sie Raster ist ziemlich gut, aber es ist schmerzhaft langsam, wenn wir ein Kontrollkästchen alle Spalten auf einmal aktivieren/deaktivieren – Quantbuff