Click here to Skip to main content
15,891,253 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
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?
Posted
Updated 30-Jan-13 23:10pm
v4
Comments
Sergey Alexandrovich Kryukov 29-Jan-13 16:01pm    
WPF is no different in terms of classes and their dependencies from anything else. Are those your own classes? If so, why would not you follow the same pattern you knew before using WPF?
—SA
cyberist 30-Jan-13 9:59am    
@Sergey I cannot follow the same pattern because in WPF I would need to to find the UIElement and then to insert its instance. I dont want to look use VisualTreeHelper.GetParent or VisualTreeHelper.GetChild everytime I need an instance. So therefore I am asking here to provide me how to do It without. Please read my question again and you will realize that I would rather stay away from traveling up the tree.
Sergey Alexandrovich Kryukov 30-Jan-13 12:23pm    
Why not?
Maybe I still don't catch the essence the problem, sorry...

By the way, are you familiar with traversal of visual and logical tree:
http://msdn.microsoft.com/en-us/library/ms753391.aspx

—SA
http://www.codeproject.com/Articles/21495/Understanding-the-Visual-Tree-and-Logical-Tree-in
cyberist 31-Jan-13 2:42am    
@Sergey I have updated my question. Please notice the VisialTree. You will see that rows dont know about headers but rows would like to get the instance of headers. Also please notice in my question that I dont want to use VisualTreeHelper which help you do the tree traversal. I dont want to run up the tree. I want to inject the instance but I dont know how.
Sergey Alexandrovich Kryukov 31-Jan-13 2:46am    
I understand...
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900