An Overview
All Eto.Forms.Control
objects have the DataContext
property.
DataContext lets us choose a data object for our View to bind to, this will likely be a ViewModel, or a data object class. But it could even be as simple as an integer (although this would be unusual).
If a View does not have or need bindings, it will likely not need a DataContext object.
The DataContext should not be used for arbitrary data storage, use Tag for this.
The relationship between DataContext and DataStore
Some Controls have a DataStore
property, a good example is the GridView.
The DataStore is similar to the DataContext, but should be used differently.
The DataStore will always be an enumerable, such as a list, array, or better yet, an ObservableCollection<T>
.
Trickle Down
A very useful feature to be aware of is the trickle-down effect of DataContext. Any Control, (including Forms and Dialogs) that has a DataContext will set the DataContext of every child control meaning that this can be accessed anywhere in your UI Tree. If a child control overrides its DataContext with a new DataContext then a new lineage of this DataContext is created.
using Eto.Forms; using Rhino.UI; class MyMainViewModel {} class MyNewViewModel {} var dialog = new Dialog() { DataContext = new MyMainViewModel(), // <-- Start of Main View Model Content = new TableLayout() { Rows = { new TableRow( // <-- TableRow has a DataContext of MyMainViewModel new StackLayout() // <-- StackLayout has a DataContext of MyNewViewModel { DataContext = new MyNewViewModel(), // <-- Start of New View Model Items = { new Drawable(), // <-- Drawable has a DataContext of MyNewViewModel new Button() // <-- Button has a DataContext of MyNewViewModel } } ), new TableRow( // <-- TableRow has a DataContext of MyMainViewModel new Button(), new Button(), // <-- Buttons all have a DataContext of MyMainViewModel new Button() ), } } }; var parent = RhinoEtoApp.MainWindowForDocument(__rhino_doc__); dialog.ShowModal(parent);