WPF is really amazing for many reasons and one of them is that it allows us to change the controls inside a control. As example if we take a ListBox. We can change the panel from StackPanel to WrapPanel and it will still work (I guess its obviously that ListBox and WrapPanel don't share any class dependencies hence why it works).
Here is an example what I mean with class dependencies.
public class Test1
{
public Test2 t;
public Test1(Test2 t)
{
this.t = t;
}
}
public class Test2
{
public string someStr;
}
Now the instance could be injected/inserting like this:
Test2 test2 = new Test2();
test2.someStr = "Hello";
Test1 test1 = new Test1();
test1.t = test2;
Or instance could be inserted like this:
Test2 test2 = new Test2();
test2.someStr = "Hello";
Test1 test1 = new Test1(test2);
There are few other ways to do this but I hope that you guys now get the point.
So now after we know how to inject the instance lets try to do so in WPF with this following example:
I have a CustomControl. My CustomControl is a little bit complex because it has rows and columns. Futhermore the CustomControl is not derivering from a DataGrid. In fact it is derivering from an ItemsControl.
As I mentioned it has columns and rows or to be more precise the rows need to know about the columns. Thats where I would like to insert the instance of columns in a row. How do i do that in WPF?
Here is a simple plain example of my problem:
Lets say the VisualTree of the CustomControl looks like this:
CustomControl
+ Grid
+ Border
+ ContentPresenter
+ Headers
+ DockPanel
+ Border
+ Rows
As you can notice in VisualTree the Rows are far away from Headers and I would like to use the injection to avoid finding Headers.
The classes look like this:
class Row : ContentControl
{
List<Column> Headers;
...
}
class Headers : ContentControl
{
List<Column> Cols = new List<Column>()
public Headers()
{
this.Cols.Add(...);
this.Cols.Add(...);
}
}
How do I insert instance like this?
this.rows.Headers = columns.Cols;
How do I insert Cols which are in Headers class to the Headers property that is inside Row class?
I have searched on the internet and many people have suggested me to let the row use VisualTreeHelper and then to travel up the tree to find the Cols. In fact I tried to do so and after monitoring my CustomControl with a Performance Profiler Tool, I figured that it's exactly the step where every row stumbles up the tree to find header that takes the most of the time. Therefore lets not use VisualTreeHelper and lets use Injection.
Any suggestions? Is there a pattern for this?