DCSIMG
WPF, "The American Dream" - Ariel's Remote Data Center

WPF, "The American Dream"

Posted Jul 23 2007, 12:42 AM by Ariel Ben Horesh  

You gotta love WPF, it's an amazing technology frightfully overwhelming but so overwhelming powerful as well.

You can create applications which are so elegant that it's make you wanna cry.

 Well, I guess all this opening is pretty nosense to you all, I didn't add anything new to you, even if you don't code with WPF (which most chances you don't, but that for another post), you could probably recite the same sentences word by word, Power to the media!.

So obviously I'm not going to tell you things you already know I just wrote down one of the lesser pieces of elegant code for WPF app, that I had to share it with you.

It's all started with a pretty reasonable scenario :

I have a parent custom control and a child custom control, each are doing important things at OnRender.

<Style x:Key="{x:Type local:MyDeck}" TargetType="{x:Type local:MyDeck}"> 
 
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type local:MyDeck}">
        <local:MyCard x:Name="myCard" Width="50" Height="50"/>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style> 
 

So you see? we have our parent MyDeck and the child MyCard.

Now, something in MyDeck is happening and it's need to render itself (for the novices, now it's time to remember that rendering doesn't occur all the time like in Winforms but just when it needed to be done).

So everything is good, and everybody's happy, right? WRONG.

What about MyCard?

If MyDeck got rendered isn't it implied that all his children need to be rerendered as well? apparently not.

"Interesting..." I tell myself, let's try to search for it, to my surprise what I thought to be a rather common scenario and something starters to WPF get themselves bumped into all the time, turn out to bring rather scarce output.

After I overcome my fear of being laughed upon for raising such a "noob" question I asked the legendary Tamir for help.

Tamir told me to try to call render manually.

Sounds pretty bad, such a common scenario and a solution which break down all kind sophisticated mechanisms build into WPF.

But after I found out no other solution I went down this road.

Brute Force? it is then. Let's use WPF's ramming device, walking trough the Visual Tree.

Let's consider the next code:

protected override void OnRender(DrawingContext drawingContext)
{ 
 
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(this); i++)
 
{
    DependencyObject visual = VisualTreeHelper.GetChild(this, i);
    if (visual is FrameworkElement)
    {
      FrameworkElement element = (FrameworkElement)visual;
      element.InvalidateVisual();
    }
}
 
...
 
...
 
}
 

Ain't pretty right? 

So what we are doing here is going on to all children and one by one telling them to render, mission accomplished, everything is Shiny now.

I don't know, disappointed a bit, does anybody knows better solutions to this problem? maybe something more elegant?

Ariel

P.S, I couldn't finish with such a dark mood, I gotto recommend you Snoop, which is a must have tool for all WPF writers out there! right along with Reflector.

Technorati Tags:
תגים:


Comments

DrorEngel said:

hi Ariel,

try to change the styles so the code snippet will be in different color or different background color, it's more pleasent to read it in such way

Dror.

# July 23, 2007 12:23 PM

Ariel Ben Horesh said:

Thanks Dror, what do you think now?

# July 23, 2007 8:55 PM

Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: