Wie zum Bearbeiten von Zeilen in einer WPF-DataGrid mit einer benutzerdefinierten RowStyle
Ich brauchen, um einige Daten in einem DataGrid
mit einer benutzerdefinierten UserControl
für jede Zeile. Die Anzeige der Daten funktioniert Prima, aber wenn ich Bearbeiten Sie die Felder in den benutzerdefinierten UserControl
gebundene Datensätze nicht ändern.
Wenn ich einen ListBox
zur Anzeige der Daten statt, es funktioniert alles wie erwartet. Aber eher würde ich das DataGrid, das es ermöglicht, Sortier-und (hoffentlich) hinzufügen neuer Datensätze.
Um zu veranschaulichen, hier ist eine einfache Daten-Klasse, die ich brauchen anzeigen (und Bearbeiten) - Personen und deren Ehegatten:
public class PersonViewModel : INotifyPropertyChanged
{
public PersonViewModel(string name)
{
_name = name;
}
private string _name = null;
public string Name
{
get { return _name; }
set
{
_name = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
private PersonViewModel _spouse = null;
public PersonViewModel Spouse
{
get { return _spouse; }
set
{
_spouse = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("Spouse"));
}
}
public event PropertyChangedEventHandler PropertyChanged = (s, e) => { };
}
..und hier ist die benutzerdefinierte UserControl (PersonView):
<UserControl x:Class="TestDataGrid.PersonView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!--Editing in DataGrid works only if these bindings use UpdateSourceTrigger=PropertyChanged-->
<TextBox Text="{Binding Path=Name}" Width="70" />
<TextBlock Text="is married to" Margin="6,0" Grid.Column="1" />
<TextBox Text="{Binding Path=Spouse.Name}" Width="70" Grid.Column="2" />
</Grid>
</UserControl>
Schließlich das Hauptfenster (mit code-behind) setzen Sie alle zusammen:
<Window x:Class="TestDataGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestDataGrid"
Title="MainWindow" Height="350" Width="500">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!--Changes made here correctly update the persons' names,
and the changes are reflected in the DataGrid below-->
<ListBox x:Name="_listbox" >
<ListBox.ItemTemplate>
<DataTemplate>
<local:PersonView />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!--Changes made here never reach the PersonViewModels..-->
<DataGrid x:Name="_datagrid" Grid.Column="1"
AutoGenerateColumns="False" CanUserAddRows="True" IsReadOnly="False" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Name}" Header="Name" />
<DataGridTextColumn Binding="{Binding Path=Spouse.Name}" Header="Spouse" />
</DataGrid.Columns>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate>
<local:PersonView />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.RowStyle>
</DataGrid>
</Grid>
</Window>
...
///<summary>
///Interaction logic for MainWindow.xaml
///</summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var personA = new PersonViewModel("Alice");
var personB = new PersonViewModel("Barry");
var personC = new PersonViewModel("Carl");
var personD = new PersonViewModel("Doris");
personA.Spouse = personB;
personC.Spouse = personD;
var persons = new List<PersonViewModel>() { personA, personC };
_listbox.ItemsSource = persons;
_datagrid.ItemsSource = persons;
}
}
Was kann ich tun, damit die Bearbeitung der Arbeit im DataGrid, wie in der ListBox?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich twiddled mit dem code ein bisschen und ich denke, dass ich es geschafft habe.
Erste von allen, müssen Sie eine note auf Ihrem PersonView, der sagt: "die Bearbeitung im DataGrid funktioniert nur, wenn diese Bindungen verwendet, UpdateSourceTrigger=PropertyChanged." Ich fand, dass es notwendig ist, UpdateSourceTrigger, aber ich verwendet, LostFocus, um zu versuchen und zu halten das gleiche Verhalten wie in der ListBox.
Zweiten, anstelle von 2 DataGridTextColumns und DataGrid.RowStyle, ich eine einzelne DataGridTemplateColumn. Ich hoffe, das ist akzeptabel--es scheint, dass die Art und Weise, Sie hatten es vor, die Vorlage war nicht wirklich zu Ehren, die Spalten, aber es funktioniert jetzt.
Nachdem Sie diese änderungen vorgenommen haben, ich sah es aktualisieren auf beiden Seiten.
Ich hoffe das hilft dir.