Sto cercando di utilizzare il collegamento dati per associare una ObservableCollection all'elemento ItemsSource di un DataGrid, mentre imparo su WPF e altre cose.Perché il binding del datacontext MainWindow in XAML non funziona come il binding nel codebehind con this.datacontext = this?
Nel codice sottostante posso impostare DataContext con this.DataContext = this;
o bloopDataGrid.DataContext = this;
. Va bene e dandy.
ho pensato che avrei potuto provare qualcosa di simile
<Window.DataContext>
<local:MainWindow/>
</Window.DataContext>
nella mia finestra principale, ma questo causa un'eccezione Stack Overflow come spiegato nel this question. Bene, questo ha un senso.
Dopo aver letto this e ad altre domande/risposte che dicono di provare DataContext="{Binding RelativeSource={RelativeSource Self}}"
nel codice XAML della finestra, ho pensato che avrei potuto effettivamente fare questo. Apparentemente I non può. O almeno, l'IDE me lo consente ed è sintatticamente corretto, ma non fa quello che voglio (cioè, esattamente ciò che fa this.DataContext = this;
).
poi ho letto this sull'utilizzo "{Binding ElementName=, Path=}"
e ha cercato di usarla in questo modo:
<DataGrid
Name="bloopDataGrid"
Grid.Row="1"
ItemsSource="{Binding ElementName=testWin, Path=OutputCollection}">
</DataGrid>
che inoltre non funziona. Forse non per lo stesso motivo, ma non riesco a capire il problema con esso.
Stranamente, non riesco a replicare l'esempio di rebinding mostrato in Rachel Lim's blog post.
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; }
}
}
}
Il codice di cui sopra è quello che sto usando per testare questo, ed è attualmente utilizzando il code-behind versione che correttamente mi dà
Che cosa sto facendo male, che mi impedisce di ottenere gli stessi risultati dell'immagine sopra ma utilizzando XAML per la gestione di DataContext? Non sto collegando i punti correttamente? ... mi mancano alcuni punti?
Ho detto che questo non ha funzionato per me e che ho capito qual è il problema con MainWindow guardando l'altra domanda a riguardo. – Hydronium
Il tuo problema è che stai mettendo insieme i tuoi dati all'interno della classe 'MainWindow'. Dovresti creare un ViewModel e implementare 'INotifyPropertyChanged'. –
Non sono sicuro di aver capito. Sono limitato a seguire il pattern MVVM per tutti i miei programmi in WPF? Come farà una nuova classe a risolvere il problema che ho? Preferisco ripararlo o capire perché non funziona, non evitarlo rigorosamente solo perché non lo capisco. – Hydronium