Click here to Skip to main content
15,887,596 members
Articles / Desktop Programming / WPF
Tip/Trick

WPF: Simple Bridge between a FrameworkElement and a FramworkContentElement

Rate me:
Please Sign up or sign in to vote.
3.36/5 (5 votes)
29 Dec 2009CPOL1 min read 16K   2  
Q: Have you ever tried to embed a FramworkContentElement into a FrameworkElement inside a WPF template?Consider the following: This won't work! ...
Q: Have you ever tried to embed a FramworkContentElement into a FrameworkElement inside a WPF template?

Consider the following:

<DataTemplate>
  <TableRow>
   <TableCell>
     <Paragraph>
       <FlowDocumnet>
         <Paragraph>
           This won't work!
         </Paragraph>
       </FlowDocument>
     </Paragraph>
   </TableCell>
  </TableRow>
</DataTemplate>


I found this problem and solution in the April 2009 ed. of MSDN. The article is about 'Dynamic WPF' How to data bind in flow documents. The problem and solution in the article is how do you create a data bound list item which can be copied and pasted using the windows clipboard in a document? The solution to that goes beyond the topic of this tip and can be found at: Code for "Create Flexible UIs with Flow Documents And Data Binding"[^]. However I thought section on creating a 'bridge' between FrameworkElements and FrameworkContentElements was a good candidate for a short tip/trick on WPF.

You may ask your self why build a bridge when there are already bridges hosted in the .NET WPF framework such as: BlockUIContainer and TextBlock? Well if you need to do more then simple 'in lines' you will need something different other then what the frame work has to offer.

Here is the solution as it appears in MSDN for creating a bridge:

Figure 1 - Fragment Class


[ContentProperty("Content")]
public class Fragment : FrameWorkElement
{
  private static readonly DependancyProperty ContentProperty =
  DependanceProperty.Register("Content", 
                              typeof(FrameworkContentElement),
                              typeof(Fragment));

  public FrameworkContnetElement Content
  {
    get
    {
      return (FrameworkContentElement)GetValue(ContentProperty);
    }
    set
    {
      SetValue(ContentProperty, value);
    }
  }
}


Now the folloing is possible:

<DataTemplate>
  <flowdoc:Fragment>
    <TableRow>...</TableRow>
  </flowdoc:Fragment>
</DataTemplate>


Figure 1 is the bridge which is really just a wrapper for the FrameworkContnetElement. However a helper method is required when displaying the data in the content element. The helper really where the trick is implemented. There is a problem encountered when re displaying the data in the Framework Element. The problem is that when displaying the data an enumerator is created and this causes an exception to be thrown. "Collection Modified..."

Here is the workaround in the help class:

Figure 2 - Helper Method



public static FrameworkContentElement LoadDataTemplate(
                                      DataTemplate dataTemplate)
{
  object content = dataTemplate.LoadContent();
  if(content is Fragment)
    return(FrameworkContentElement)((Fragment)content).Content;
  else if(content id TextBlock)
  {
   InlineCollection inlines = ((TextBlock)content).Inlines;
   if(inlines.Count == 1
     return inlines.FirstInline;
   else
   {
     Paragraph paragraph = new Parageraph();
     while(inlines.FirstInline != null)
      paragraph.Inlines.Add(inlines.FirstInline);
     return paragraph;
   }
  }
  else
   throw new Exception("Data Template needs to contain a <Fragment> or <TextBlock>");
}

License

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


Written By
CEO AW Proto-Code, Inc.
United States United States
I’m a self learned wiz kid turned Architect. Stared with an Apple IIe, using AppleSoft Basic, ProDos and Begal Basic at age 10.

Picked up LPC in college before the Dot Com Explosion. Wrote some Object C in the USAF for one of my instructors. Got a break from a booming computer manufacture testing server software. Left the Boom and went to work for a Dot Com built from the ashes of Sun Micro in CS. Mentoring in Java solidified me as a professional developer. Danced in the light of the sun for 13 years, before turning to the dark side. An evil MVP mentored me in the ways of C# .NET. I have not looked back since.

Interests include:

~ Windows Presentation Foundation and Silverlight
~ Parallel Programming
~ Instruction Set Simulation and Visualization
~ CPU to GPU code conversion
~ Performance Optimizations
~ Mathematics and Number Theory
~ Domain Specific Languages
~ Virtual Machine Design and Optimization
~ Graphics Development
~ Compiler Theory and Assembler Conversion Methodology
~ CUDA, OpenCL, Direct Compute, Quantum Mechanics

IEEE Associate Member 2000
This is a Organisation (No members)


Comments and Discussions

 
-- There are no messages in this forum --