I'm getting started with WPF and finding it difficult to get even the most simple binding working. Here's some givens…
I have an object that queries an existing database and returns a "datatable" object, the data comes back (and for test purposes, only a single row and single column called "MyTextColumn")
The data table is not "Strongly typed" as I've read in other places trying to force the issue of strongly typed objects. I want to understand the underlying mechanisms from the code-behind perspective, AND not from the XAML perspective. From reading, apparently you can't bind directly to a data table, but you can to the "DefaultView" of a DataTable object (makes no sense to me since they point to same record (or set of records, with exception of say a filter of some type).
So, in the XAML portion of the window,
<src:MyWindow blah, blah >
<Grid Name="grdTesting">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Name="lblMyTextColumn"
Content="Just the label"
Grid.Row="0" Grid.Column="0 "/>
<TextBox Name="txtMyTextColumn"
Grid.Row="0" Grid.Column="1"
Width="120" />
</Grid>
</src:MyWindow>
So now, I'm in the code-behind, what I've read is you have to have a BindingListCollectionView oView;
public partial class MyWindow : Window
{
BindingListCollectionView oView;
MyQueryingManager oTestMgr;
public MyWindow()
{
InitializeComponent();
oTestMgr = new MyQueryingManager();
DataTable oResults = oTestMgr.GetTheData();
// Data context for the form bound to the Table retrieved
oView = new BindingListCollectionView( oResults.DefaultView );
// One place said the Window should get the binding context
DataContext = oView;
// another indicated the grid... Just need to know which I SHOULD be using
grdTesting.DataContext = oView;
// Now, for my binding preparation...
Binding bindMyColumn = new Binding();
bindMyColumn.Source = oView;
bindMyColumn.Path = new PropertyPath("MyTextColumn");
txtMyTextColumn.SetBinding( TextBox.TextProperty, bindMyColumn );
}
}
So… what am I missing here… Should be simple, nothing complex, I have a data table, with a record, that has a value. Run the form (no matter binding context to the Window or the Grid), and the record value does not show in the textbox control. Once I understand the behavior on a single textbox, I can go on with all the other elements (validation, input mask, formatting, etc), but am stuck right at the gate on this one.
Thanks
Best Answer
First, you can bind to a
DataTable
but you can also use the default view (which is aDataView
) etc.Usually, you bind a
DataTable
to anItemsControl
or a control that derives from it, such asListBox
,DataGrid
etc. Then each container will get aDataRow
(orDataRowView
) and the binding will be easy.Since you are binding it directly to a
TextBox
inside aGrid
you would have to specify bothRow
andColumn
in the binding. The correct path to bind to the column named "MyTextColumn" in the first row isRows[0][MyTextColumn]
Try this
A problem if you're binding directly to the
DataTable
is that it doesn't implementINotifyPropertyChanged
so the UI won't know that the value has changed if it is changed from some other source. In this case, you can use aDataView
instead. The binding syntax will be a little different here since you access theDataRowViews
directly with the index operator.