I have a DataSet
bound to the Window.DataContext
; I also have a DataGrid
:
<DataGrid ItemsSource={Binding Tables[Items]}>
<DataGrid.Columns>
<DataGridTextBoxColumn Header={Binding Path=DataContext.Tables[Names]/Test, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}} />
</DataGrid.Columns>
</DataGrid>
Basically, I'm trying to bind the Header of that column to DataTable "Names", Column "Test", first row.
However, I can't get it right. Note that I can bind it fine outside the DataGrid. The Grid's ItemsSource changes the data context and I don't know how to refer outside to the original DataContext.
It seems that the binding succeeds; but the problem is that the current item (first row) of the Tables[Names] in the Window.DataContext got lost.
If I make the DataSet static and access it via {x:Static local:dataset} then things work fine. But I can't use static datasets because there will be multiple instances (multi-user).
Can anyone please point me in the right direction?
Don't know if this will work for you situation, but you could try something like this: 1) Give your Window a Name attribute e.g. Name=ZeWindow. 2) Bind your
DataGridTextBoxColumn
Header like this:So basically, instead of binding to the
DataContext
of theDataGrid
, you bind to theDataContext
of theUIElement
with Name=ZeWindow.P.S.: I'm pretty new to WPF, so this might not work with the Window, but I did something similar using UserControls
This is the expected behaviour actually: The
DataContex
t forDataGridCell
is the entireRow.so you have 3 solutions: either you add your binding in code behind like this:
in each Column's Constructor:
(you have to find a way to get the "thisColumnIndex". As far as I'm concerned, I add the columns right after I create them, si I simply put "dataGridOwner.Columns.Count" there).
or...
you can find a way to get the dataContext you want on each cell (tried that but it messes up badly when column/row virtualization is on)
or...
have a look there:
Binding a cell object's property to a DataGridCell in WPF DataGrid
I personally find the first one to be the better for my purpose (since I add my columns in code behind anyway), but this is really up to you in the end...
As far as columnHeaders are concerned (and only columnsHeaders, not rows), you might also explore the "DataTemplate" way:
set the columns' header to the Column itself (that way you set the column as DataContext for the header) and use a DataTemplate.
e.g.:
in each column class:
and in your dataGrid's xaml, something like:
of course, my "MyDataGridColumnHeader" class contains definitions for all the properties referenced here.
hope this helps.
I'm pretty sure you could do what you're trying to do by using
RelativeSource
binding.I made a quick example at: http://bitbucket.org/claus/wpf-bindingoutsidedatacontext
It allows you to bind to the parent Window, which in my case has the viewmodel as datacontext (with the SomethingOutsideDataContext property on it).
You should be aware though, this will only work with WPF and not Silverlight - the 'FindAncestor, AncestorType' stuff has not been implemented in Silverlight yet... I'm not sure if there's another method, besides using static resources.