WPF DataGrid. Kampf um Vorlage

Hallo allerseits!

Ich hoffe, dass ich durch meinen Artikel das Problem der Verknüpfung der XML-Darstellung des DataGrid mit seiner Codesammlung klären kann. Verwenden Sie dazu am besten ein konkretes Beispiel. Wir müssen also die Liste der Elemente einer Struktur in die Tabelle einfügen. Angenommen, die Elemente selbst sehen im Code folgendermaßen aus:

class Element { public Element (string firstName, string lastName, string phoneNumber, DateTime date) { this.firstName = firstName; this.lastName = lastName; this.phoneNumber = phoneNumber; this.date = date; } public string FirstName { get { return this.firstName; } set { this.firstName = value; } } public string LastName { get { return this.lastName; } set { this.lastName = value; } } public string PhoneNumber { get { return this.phoneNumber; } set { this.phoneNumber = value; } } public DateTime Date { get { return this.date; } set { this.date = value; } } private string firstName; private string lastName; private string phoneNumber; private DateTime date; } 

Dementsprechend sieht ihre Liste folgendermaßen aus:

 List<Element> elements = new List<Element>(); 

Kommen wir nun zum DataGrid. Da dies alles das gleiche WPF ist, können Sie es mit Ihren Händen auf das Formular ziehen. Lassen Sie die IDE den Code dafür schreiben.

 <DataGrid x:Name="dataGrid" Margin="10,103,0,15" CellEditEnding="dataGrid_CellEditEnding" Grid.RowSpan="2" Grid.ColumnSpan="2" HorizontalAlignment="Left" Width="728" AutoGenerateColumns="False"/> 

Hier setze ich manuell nur AutoGenerateColumns = "False", da wir in Zukunft die Tabellenspalten selbst bearbeiten werden.

Als nächstes müssen wir die Daten an die Tabelle binden, wobei jedes Feld des Elements der Spalte der Tabelle entsprechen muss.

 <DataGrid.Columns> <DataGridTextColumn Header="" Binding="{Binding Path=FirstName}"/> <DataGridTextColumn Header="" Binding="{Binding Path=LastName}"/> <DataGridTemplateColumn Header="" SortMemberPath="PhoneNumber"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}" /> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="" SortMemberPath="Date"> <DataGridTemplateColumn.CellTemplate> <DataTemplate > <TextBlock Text="{Binding Path=Date, StringFormat='dd/MM/yyyy'}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding Date}"/> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> </DataGrid.Columns> 

Hier werden zwei Arten von Spalten DataGridTextColumn und DataGridTemplateColumn verwendet. Über ihre Typen kann man überall nachlesen. Das Wichtigste, was Sie hier verstehen müssen, ist, dass Sie mit Hilfe von DataGridTemplateColumn eine beliebige Vorlage festlegen können. Das heißt, in die Zellen dieser Spalte können beliebige Steuerelemente (Schaltflächen, Kalender usw.) eingefügt werden. In der dritten Spalte befindet sich beispielsweise eine TextBox:

 <DataGridTemplateColumn Header="" SortMemberPath="PhoneNumber"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> 

WICHTIG: Vergessen Sie nicht, den Header zu registrieren, da die automatische Vervollständigung für uns deaktiviert ist. Und auch für DataGridTemplateColumn muss SortMemberPath registriert werden, damit er weiß, nach welchem ​​Feld die Daten sortiert werden sollen.

Fahren wir fort mit Binden. Dies ist die Datenbindung selbst. Wir geben es mit Binding Path = PhoneNumber an. Hierbei ist vor allem zu berücksichtigen, dass dies der Name der Klassenmethode ist, die den Wert des Feldes zurückgibt (nicht phoneNumber, sondern PhoneNumber, siehe Klassenbeschreibung).
Und noch eine Sache. Es ist möglich, verschiedene Arten von Vorlagen (DataTemplate) für Zellen im Normalzustand (CellTemplate) und im Bearbeitungszustand (CellEditingTemplate) einzugeben. In der vierten Spalte der Zelle befindet sich im Normalzustand eine TextBox und im Bearbeitungszustand DatePicker:

 <DataGridTemplateColumn Header="" SortMemberPath="Date"> <DataGridTemplateColumn.CellTemplate> <DataTemplate > <TextBlock Text="{Binding Path=Date, StringFormat='dd/MM/yyyy'}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding Date}"/> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> 

Beachten Sie auch, dass das Textfeld bei der Arbeit mit Datumsangaben eine StringFormat-Eigenschaft hat, die formatiert werden kann. Es ist wichtig, dass für die korrekte Anzeige des Monats "MM" groß ist.

Um nun bestimmte Daten an die Tabelle zu binden, kehren wir zum Code in C # zurück.
Nachdem das Array mit Elementen gefüllt wurde, muss es als Datenquelle angegeben werden:

 dataGrid.ItemsSource = elements; 

Daher werden alle Änderungen an Elementen in der Tabelle angezeigt, und umgekehrt führen alle Änderungen an der Tabelle zu Änderungen an Elementen. Wenn Sie jedoch Änderungen an Elementen vornehmen, müssen Sie die Methode aufrufen
 dataGrid.Items.Refresh(); 
.
Und als weiteres gutes Beispiel für ein C # -Paket - XML ​​- werde ich ein Beispiel für die Überprüfung der Füllung der Telefonnummernzellen mit nur Zahlen geben. Bearbeiten Sie dazu den Code in der dritten Spalte leicht:

 <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}" TextChanged="phN_TextChanged"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> 

Es ist zu sehen, dass ich im TextBox-Tag einen Handler für das Textänderungsereignis zugewiesen habe. Jetzt muss nur noch dieser Handler im Code registriert werden:

  private void phN_TextChanged(object sender, TextChangedEventArgs e) { int result = 0; TextBox txtx = sender as TextBox; if (txtx !=null) { if (!int.TryParse(txtx.Text, out result)) { txtx.Text = txtx.Text.Substring(0, txtx.Text.Length - 1); txtx.CaretIndex = txtx.Text.Length; } } } 

Das Überprüfen auf Zahlen kann auch durch reguläre Ausdrücke erfolgen.

Gute Freilassung an alle!

Source: https://habr.com/ru/post/de484968/


All Articles