tags:

views:

273

answers:

3

I am writing a WPF chart and use Visuals for performance. The code looks like:

public class DrawingCanvas2 : Canvas
{
    private List<Visual> _visuals = new List<Visual>();

    protected override Visual GetVisualChild( int index ) { return _visuals[index]; }
    protected override int VisualChildrenCount { get { return _visuals.Count; } }

    public void AddVisual( Visual visual )
    {
        _visuals.Add( visual );

        base.AddVisualChild( visual );
        base.AddLogicalChild( visual );
    }
}

Beside DrawingVisual elements (line, text) I need a ComboBox in the chart. So I tried this:

    public DrawingCanvas2()
    {
        ComboBox box = new ComboBox();
        AddVisual( box );

        box.Width = 100;
        box.Height = 30;

        Canvas.SetLeft( box, 10 );
        Canvas.SetTop( box, 10 );
    }

but it does not work, there is no ComboBox displayed. What I am missing?

+1  A: 

Have you considered just putting the ComboBox inside of a container Panel along with the DrawingCanvas2, and on top of the DrawingCanvas2 in terms of z-order?

That way your DrawingCanvas2 can concentrate on drawing Visuals and your ComboBox will behave out-of-the-box.

micahtan
Interesting approach, it works, I put both `DrawingCanvas2` and `ComboBox` inside `Canvas`
Mikhail
A: 

The Canvas will "get" its size from its Children property (using the MeasureOverride and ArrangeOverride). Since you just call the AddVisualChild it's not added to the Children property and it still thinks it is empty.

The Children property is an UIElementCollection (ComboBox is an UIElement)

A: 

The right answer is by Linda Liu, Microsoft WPF forum, although XIU came close to it.

the code is:

    public DrawingCanvas2() : base()
    {
        ComboBox box = new ComboBox();
        AddVisual( box );

        Size outputSize = new Size( 100, 20 );

        box.Measure( outputSize );
        box.Arrange( new Rect( outputSize ) );
        box.UpdateLayout();

        box.Items.Add( "hello1" );
        box.Items.Add( "hello2" );
        box.Items.Add( "hello3" );

        box.SelectedIndex = 1;
    }

It is important to note that box.SelectedIndex must be explicitly set to not -1, else the items in the box are not-choosable.

Mikhail