Hosting a Visual in a Grid

I want to take a ContainerVisual and display it in my WPF window. All of the
Panel classes have a Children property, but the Children property is a
UIElementCollection not a VisualCollection so doing something like

ContainerVisual contVis = new ContainerVisual();
Grid grid = new Grid();
grid.Children.Add( contVis );

results in a compiler error. Is there some other way to go about this

Note that the above example is somewhat contrived, I actually have a custom
class derived from Visual that I am working with, but the same problem still
applies. The only way I can get it to compile is by doing something like:

VisualOperations.GetChildren( grid ).Add( contVis );

Is this the correct way of going about this Currently nothing gets
displayed from my Visual object when I do that. It also seems like a hack if
it is the right thing to do.

Thanks,
  Tony


Answer this question

Hosting a Visual in a Grid

  • MS makes it difficult

    That didn't seem to work for me. I received the following exception:
     
    ArgumentException - The parameter belongs to unexpected type 'System.Windows.Media.ContainerVisual'. Expected types are 'System.Windows.UIElement','System.Windows.Controls.ColumnDefinition', 'System.Windows.Controls.RowDefinition'.
     
    Thanks,
      Tony

  • brusi

    Hmm... yeah I guess that makes sense now that I think about it. IAddChild is about logical children, so it would make sense that the object only accepts types that it logically expects. I guess VisualOperations is your only route after all.

    Cheers,
    Drew

  • GoslaMettina

    Using the VisualOperations class is working for me now. I had to do some work to get things working, but I was wondering if this is the way you should add Visual derived objects (that don't inheirit from UIElement) into your app or if there is a better way of doing it.
     
    Thanks,
      Tony

  • Vlash

    I replied to this in the newsgroup already, but figured I'd reply here as well for history's sake:

    You should be able to cast any Panel to IAddChild and then call AddChild passing the Visual.

    HTH,
    Drew

  • Murtaza Zaidi

    There are a couple of other options besides using VisualOperations.

    The first would be to inherit from UIElement rather than ContainerVisual. It sounds like an explicit choice was already made to avoid inheriting from UIElement, however, so perhaps that's not appropriate here.

    The second option is to write a small wrapper class, inheriting from UIElement, which has a "content" property of type visual (or VisualCollection, if you prefer, in which case "Children" would be a better name for the property). You would have to use VisualOperations to implement that class, but the difference is that you'd only be accessing your own class' child collection, rather that the Grid's. As a side advantage, you'd be able to use your class and, by extension, your ContainerVisual, from XAML.

    The reason to consider one of the above two options is that using VisualOperations to poke Visuals or other Visual properties directly into a FrameworkElement is risky, as some elements can deal fine with it but others can't. When it does work, there is no way to know whether it will always work or whether you are getting lucky with the particular scenario. In general, I strongly recommend that you not use VisualOperations on classes you don't own, except for read-only operations.



  • Hosting a Visual in a Grid