I am trying to use Data binding to bind an ObservableCollection to the ItemsSource of a DataGrid, as I learn about WPF and stuff.
In the code-behind I can set the DataContext with this.DataContext = this;
or bloopDataGrid.DataContext = this;
. That's fine and dandy.
I thought I could try something like
<Window.DataContext>
<local:MainWindow/>
</Window.DataContext>
in my main window, but this causes a Stack Overflow Exception as explained in this question. Fine, that makes some sense.
After reading this and other questions/answers that say to try DataContext="{Binding RelativeSource={RelativeSource Self}}"
in the window's XAML code, I thought I could actually do this. Apparently I cannot. Or at least, the IDE lets me and it's syntactically correct, but does not do what I want (ie, exactly what this.DataContext = this;
does).
Then I read this about using "{Binding ElementName=, Path=}"
and tried to use it like so:
<DataGrid
Name="bloopDataGrid"
Grid.Row="1"
ItemsSource="{Binding ElementName=testWin, Path=OutputCollection}">
</DataGrid>
Which also doesn't work. Maybe not for the same reason, but I can't figure out the problem with it.
Oddly, I can't replicate the rebinding example shown 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; }
}
}
}
The above code is what I'm using to test this, and is currently using the code-behind version which correctly gives me
What am I doing wrong, which is preventing me from getting the same results as the above picture but by using XAML for the DataContext handling? Am I not connecting the dots properly? ...am I missing some dots?