2016-07-27 10 views
0

Ich habe DataGrid mit ItemsSource an ObservableCollection in ViewModel gebunden. DataGrid ermöglicht die Auswahl mehrerer Zeilen. ViewModel abonniert ein Ereignis (von einem Dienst), und die Behandlung dieses Ereignisses umfasst das Entfernen eines Objekts aus ObservableCollection. Wenn dieses Objekt eines der ausgewählten Objekte ist, passiert etwas Seltsames mit markierten Zeilen in DataGrid. Ich weiß nicht, wie genau es zu erklären ist, also hier ist ein BildDie SelectedItems und markierten Zeilen von DataGrid werden nach dem Löschen der ausgewählten Zeile nicht synchronisiert

image.

Hier ist Code, der das Problem reproduziert. Schaltfläche in der Symbolleiste hinzugefügt, die das dritte ausgewählte Element entfernt. Stellen Sie daher vor dem Drücken der Taste sicher, dass Sie mehr als 5 Elemente auswählen.

Ansichtsmodell

public class MyViewModel 
{ 
    public ObservableCollection<MyObject> MyItems { get; set; } 

    public MyViewModel() 
    { 
     MyItems = new ObservableCollection<MyObject>(); 
     for (int i = 0; i < 1000; i++) 
     { 
      MyItems.Add(new MyObject("name" + i, i)); 
     } 
    } 
} 

Ansicht (XAML)

<Window x:Class="ItemsChangedTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:ItemsChangedTest" 
     Title="MainWindow" Height="350" Width="525"> 
    <DockPanel> 
     <ToolBar DockPanel.Dock="Top"> 
      <Button Content="Test" Click="TestButton_Click"/> 
     </ToolBar> 
     <DataGrid Name="MyDataGrid" ItemsSource="{Binding MyItems, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" /> 
    </DockPanel> 
</Window> 

-Code-behind (hinzugefügt Tastenhandler dieses Verhalten zu testen)

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     DataContext = new MyViewModel(); 
     InitializeComponent(); 
    } 

    private void TestButton_Click(object sender, RoutedEventArgs e) 
    { 
     (DataContext as MyViewModel).MyItems.Remove(MyDataGrid.SelectedItems[2] as MyObject); 
    } 
} 

Model (einfache Klasse)

public class MyObject 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 

    public MyObject(string name, int age) 
    { 
     Name = name; 
     Age = age; 
    } 
} 
+0

von dem, was Sie sagen, scheint, dass das Datenraster entfernt das Element und sie heben die Auswahl aus der Liste mit der gleichen ID. Ich sehe kein Problem in Ihrem Code. Wenn es sich um einen DataGrid-Fehler handelt, sollten Sie eine ObservableCollection SelectedItems im View-Modell verwalten. Und setzen Sie die DataGrids mit Ihren konsequent – alessalessio

+0

@alessalessio, bekomme ich diesen Fehler beim Versuch, SelectedItems zu binden - "'SelectedItems Eigenschaft ist schreibgeschützt und kann nicht aus Markup gesetzt werden." – vlada

Antwort

0

Fügen Sie eine Datagrid-Aktualisierung hinzu und fokussieren Sie nach dem Löschen.

private void TestButton_Click(object sender, RoutedEventArgs e) 
    { 
     (DataContext as MyViewModel).MyItems.Remove(MyDataGrid.SelectedItems[2] as MyObject); 
     MyDataGrid.Items.Refresh(); 
     MyDataGrid.Focus(); 
    } 
+0

Ich kann das nicht tun, da die Methode, die das Entfernen von ObservableCollection (Handler für ein Ereignis, das von einem anderen Dienst stammt) in ViewModel befindet. – vlada

+0

Dann können Sie diesen Service-Code buchen. –

+0

Relevanter Teil des Ereignishandlers ist 'MyItems.Remove (someItem);' Fehler tritt auf, wenn someItem in DataGrid.SelectedItems ist – vlada

0

Immer dann, wenn eine der ausgewählten Zeilen bekommt 2 Ereignisse entfernt werden genannt:

DataGrid.SelectedCellsChanged heißt erste und in SelectedCellsChangedEventArgs.RemovedItems sind alle Zellen, die von Zeile, die nach der Zeile ist, die entfernt werden muss. Diese Zeile nach muss nicht in Auswahl sein, aber wenn es dann ist, verliert sie den ausgewählten Zeilenstil, der meiner Meinung nach nicht wie erwartet funktioniert.

DataGrid.SelectionChanged wird zweite genannt und in SelectionChangedEventArgs.RemovedItems enthält nur Zeile, die entfernt werden soll (funktioniert wie erwartet).

Verwandte Themen