Hallo!
verwende MVVM um meine Formulare vom Code zu trennen.
Jetzt habe ich ein Fenster, in dem ein paar TextBoxen sind und ein DataGrid, welches eine Liste mit Objekten zeigt, die jedoch nicht bearbeitbar sein sollen. Sieht prinzipiell so aus:
<DataGrid ItemsSource="{Binding Employees}" SelectedItem="{Binding CurrentEmployee}" Grid.Row="1" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" CanUserAddRows="False" CanUserDeleteRows="False" IsReadOnly="True">
<DataGrid.Columns>
...
</DataGrid.Columns>
</DataGrid>
Das funktioniert auch, aber wenn ich in dem Formular eine BindingGroup hinzufüge, wird der "CurrentEmployee" in meinem ViewModel nicht mehr gesetzt.
<Window.BindingGroup>
<BindingGroup>
<BindingGroup.ValidationRules>
<helpers:CompanyValidationRule />
</BindingGroup.ValidationRules>
</BindingGroup>
</Window.BindingGroup>
Habe leider keine Ahnung an was das liegen könnte.
Ich habe das Problem leider immer noch.
Als Workaround kann ich natürlich das SelectionChanged-Event des DataGrids verwenden, um mein ViewModel zu aktualisieren. Das ist aber nicht Sinn vom MVVM und außerdem Fehleranfällig.
private void DataGrid_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
(DataContext as CompanyViewModel).CurrentEmployee = (sender as System.Windows.Controls.DataGrid).SelectedItem as Employee;
}
Hat denn niemand eine Idee?
kannst du ein sample-Projekt bauen, zippen, und anhängen?
Ich würde mir das gerne mal angugge, aber extra deswegen ein sample-Projekt zu bauen ist mir zu viel.
Der frühe Apfel fängt den Wurm.
OK. Anbei die stark vereinfachte Mini-Testanwendung.
Unterhalb des DataGrids habe ich eine Textbox, die den Namen des aktuell gesetzten Mitarbeiters aus dem ViewModel anzeigt.
Wenn im DataGrid einer ausgewählt wird, so erscheint er leider nicht, da im ViewModel gar keine Änderung am CurrentEmployee ankommt.
<Window.BindingGroup>
<BindingGroup>
<BindingGroup.ValidationRules>
<my:CompanyValidationRule />
</BindingGroup.ValidationRules>
</BindingGroup>
</Window.BindingGroup>
Wenn ich die Zeilen oben mit der BindingGroup auskommentiere, dann funktionierts.
sehr empfehle ich: Binding-Picking im Xaml-Editor
Dazu muß man aber die Anwendungs-Struktur entsprechend aufbauen, ein MainViewModel etwa im App.Xaml als Resource anlegen, dass von überall dran gebunden werden kann, vlt:
<Window x:Class="DemoApplication.WindowCompanies"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Validation.ValidationAdornerSite="{Binding ElementName=labelErrors}"
xmlns:my="clr-namespace:DemoApplication" Title="WindowCompanies" Height="300" Width="300"
DataContext="{StaticResource MainModel}">
Dann kannman auch das richtige Binding picken, um die Textbox ans CurrentItem zu binden:
<TextBox Text="{Binding Path=Employees/LastName}" Grid.Column="1" Grid.Row="2" Margin="2" />
Der frühe Apfel fängt den Wurm.
Danke schonmal. Das funktioniert schon mal bei dem einfachen Beispiel.
In meiner Anwendung ist jedoch im Moment darauf angewiesen, dass die Eigenschaft CurrentEmployee im ViewModel bei der Aktualisierung gesetzt wird. Das geschieht in deiner Version jedoch auch nicht.
<DataGrid ItemsSource="{Binding Employees}" SelectedItem="{Binding CurrentEmployee}" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" CanUserAddRows="False" CanUserDeleteRows="False" IsReadOnly="True">
Meine Datenbindung der TextBox hatte übrigens funktioniert, bis ich die Validierung hinzugefügt habe.
Tja, das mit dem Binding des SelectedItems ins Viewmodel kriege ich auch nicht gebacken, wenn dieses Validation-Dings drinne ist.
Mir kommt das wie Bug vor.
In MVVM User-Auswahl ins Viewmodel stelle ich eine Alternative vor:
Die CollectionView ins Viewmodel verlagern, dann weiß das Viewmodel auch ohne zusätzliches Binding, was grad selektiert ist.
Der frühe Apfel fängt den Wurm.
OK. Jetzt weis ich wenigstens, dass ich nicht grundlegend was falsch gemacht habe.
Da ich bereits alle ViewModels in meinen Anwendungen nach einem ähnlichen Muster aufgebaut habe, werde ich erst einmal bei meinem Workaround von oben bleiben.
Trotzdem Danke!!