This is the first time I am launching WPF, and I am struggling with how to bind controls to a class that is created using the composition of other objects. For example, if I have a Comp class that consists of two separate classes (note the various elements that were omitted for clarity):
class One { int _first; int _second; } class Two { string _third; string _fourth; } class Comp { int _int1; One _part1; Two _part2; }
Now I understand that I can easily bind _int1 using the "get" defined in Comp. But how do I get attached to the _part1._first, _part1._second elements. Do I provide getters for them at the Comp class level? or can I expose them in composite classes and use a binding path that points to them? And how does this work with setting properties?
So is this a pattern?
.... <TextBlock Name="txtBlock" Text="{Binding Path=Third}" /> .... class One { int _first; int _second; } class Two { string _third; string _fourth; } class Comp { int _int1; One _part1; Two _part2; int Int1 { get { return _int1; } set { _int1 = value; } } int First { get { return _part1._first; } set { _part1._first = value; } } int Second { get { return _part1._second; } set { _part1._second = value; } } string Third { get { return _part2._third; } set { _part2._third = value; } } string Fourth { get { return _part2.fourth; } set { _part2._fourth = value; } } } ... Comp oComp = new Comp(); txtBlock.DataContext = oComp; ...
Or is it a template? (where I'm not sure what to put in the way)
.... <TextBlock Name="txtBlock" Text="{Binding Path=_part2.Third}" /> .... class One { int _first; int _second; int First { get { return _first; } set { _first = value; } } int Second { get { return _second; } set { _second = value; } } } class Two { string _third; string _fourth; string Third { get { return _third; } set { _third = value; } } string Fourth { get { return _fourth; } set { _fourth = value; } } } class Comp { int _int1; One _part1; Two _part2; int Int1 { get { return _int1; } } } ... Comp oComp = new Comp(); txtBlock.DataContext = oComp; ...
Or am I on my way to rethinking MV-VM (which I am gradually starting to understand)?
.... <TextBlock Name="txtBlock" Text="{Binding Path=Third}" /> .... class One { int _first; int _second; } class Two { string _third; string _fourth; } class Comp { int _int1; One _part1; Two _part2; } class CompView { Comp _comp; CompView( Comp comp ) { _comp = comp; } int Int1 { get { return _comp._int1; } set { _comp._int1 = value; } } int First { get { return _comp._part1._first; } set { _comp._part1._first = value; } } int Second { get { return _comp._part1._second; } set { _comp._part1._second = value; } } string Third { get { return _comp._part2._third; } set { _comp._part2._third = value; } } string Fourth { get { return _comp._part2.fourth; } set { _comp._part2._fourth = value; } } } ... Comp oComp = new Comp(); CompView oCompView = new CompView( oComp ); txtBlock.DataContext = oCompView; ...
So how do I do this? If this is the first or third template, then it seems that I took all my beautiful (disparate) hierarchical data and broke it into a flat configuration so that I can bind it to user interface elements. Is this how it should happen, or is there a better way (second template?)
Edit
I left the question that I really need a two-way binding. Thus, the owners of the properties really had to get and install.
Edit
Updated my pseudo code to show setters as well as getters
Edit
I followed the pattern presented by Marc and Julien, and implemented the setters and was pleased with the result. For some reason, I convinced myself that setting a property would not follow up to the ultimate entity.