Ich versuche Data Binding zu verwenden, um eine ObservableCollection an die ItemsSource eines DataGrid zu binden, wenn ich etwas über WPF und andere Dinge erfahre. Im Code-Behind kann ich den DataContext mit this.DataContext = this;
oder bloopDataGrid.DataContext = this;
setzen. Das ist gut und gut.Warum funktioniert die Bindung des MainWindow-Datenkontexts in XAML nicht so wie die Bindung im Codebehind mit this.datacontext = this?
Ich dachte, ich so etwas wie
<Window.DataContext>
<local:MainWindow/>
</Window.DataContext>
in meinem Hauptfenster versuchen könnte, aber dies führt zu einem Stack-Überlauf Ausnahme wie in this question erläutert. Gut, das macht Sinn.
Nach der Lektüre this und anderen Fragen/Antworten, die sagen DataContext="{Binding RelativeSource={RelativeSource Self}}"
im Fenster des XAML-Code, um zu versuchen, dachte ich, ich könnte tatsächlich diesen tun. Anscheinend kann ich nicht. Oder zumindest, die IDE lässt mich und es ist syntaktisch korrekt, aber tut nicht, was ich will (dh genau was this.DataContext = this;
tut).
Dann las ich this über "{Binding ElementName=, Path=}"
mit und versucht, es wie so zu verwenden:
<DataGrid
Name="bloopDataGrid"
Grid.Row="1"
ItemsSource="{Binding ElementName=testWin, Path=OutputCollection}">
</DataGrid>
Welche auch nicht funktioniert. Vielleicht nicht aus dem gleichen Grund, aber ich kann das Problem damit nicht lösen.
Seltsamerweise kann ich das in Rachel Lim's blog post gezeigte Beispiel für eine erneute Bindung nicht replizieren.
XAML:
<Window
x:Class="DataBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525"
x:Name="testWin">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="{Binding text}">
</Label>
<DataGrid
Name="bloopDataGrid"
Grid.Row="1"
ItemsSource="{Binding Path=OutputCollection}">
</DataGrid>
</Grid>
</Window>
C#:
using System;
using System.Collections.ObjectModel; //For ObservableCollection<T>
using System.Windows;
namespace DataBinding
{
public partial class MainWindow : Window
{
public String text { get; set; }
public ObservableCollection<testStruct> OutputCollection { get; set; }
public struct testStruct
{
public testStruct(String x, String y) : this()
{
Col1 = x;
Col2 = y;
}
public String Col1 { get; set; }
public String Col2 { get; set; }
}
public MainWindow()
{
InitializeComponent();
testA t1 = new testA();
this.DataContext = this;
//this.DataContext = t1;
//bloopDataGrid.DataContext = this;
text = "bound \"this\"";
t1.text = "bound a class";
OutputCollection = new ObservableCollection<testStruct>();
OutputCollection.Add(new testStruct("1", "2"));
OutputCollection.Add(new testStruct("3", "4"));
}
public class testA
{
public String text { get; set; }
}
}
}
Der obige Code ist das, was ich verwende dies zu testen, und zur Zeit der Code-Behind-Version verwendet, die richtig gibt mir
Was mache ich falsch, was mich daran hindert, die gleichen Ergebnisse wie das obige Bild zu erhalten, aber mit XAML für die DataContext-Behandlung? Verbinde ich die Punkte nicht richtig? ... fehlen mir einige Punkte?
Ich erwähnte, dass dies für mich nicht funktioniert hat, und dass ich herausgefunden habe, was das Problem mit MainWindow ist, indem ich die andere Frage darüber ansehe. – Hydronium
Ihr Problem besteht darin, dass Sie Ihre Datenelemente innerhalb der 'MainWindow'-Klasse selbst zusammensetzen. Sie sollten ein ViewModel erstellen und 'INotifyPropertyChanged' implementieren. –
Ich bin mir nicht sicher, ob ich das verstehe. Kann ich das MVVM-Muster für alle meine Programme in WPF einhalten? Wie wird das Problem, das ich habe, durch eine neue Klasse behoben? Ich würde es lieber reparieren oder herausfinden, warum es nicht funktioniert, nicht strikt vermeiden, nur weil ich es nicht verstehe. – Hydronium