简体   繁体   中英

how to display drawingvisual on canvas above child UIElements of Canvas defined in XAML

So I have a drawingvisual Marker in VisualCollection visuals in a class deriving from canvas.

public class OverlayCanvas:Canvas
{
    VisualCollection visuals;

    DrawingVisual MarkerVisual = new DrawingVisual();
}

In the xaml I have a drag selection border defined that I wish to also be drawn.

             Components:OverlayCanvas 
                >

                <Border 
                    x:Name="dragSelectionBorder"
                    BorderBrush="White"
                    BorderThickness="0"
                    CornerRadius="1"
                    Visibility="Collapsed"
                    />
             </Components:OverlayCanvas>

How do I make both display?

Normally I would override these, but do I have to define all children of the canvas in xaml and add them to the VisualCollection? If I just override the two methods then when render calls getvisualchild, it draws only the marker DrawingVisual but it will not get the items defined in the xaml.

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

I thought perhaps that I could Panel.Children.Add but it requires a UIElement. I then thought that perhaps the correct thing was to just Visual.AddVisualChild, so I ran this code on the set marker event in the Canvas.

    {
    MarkerVisual = new DrawingVisual();
    using (DrawingContext dc = MarkerVisual.RenderOpen())
    {
      dc.DrawLine(MarkerPen, new Point(MouseHorizontalPositionInPixels, YPositionForStartOfVerticalAxisLines),
        new Point(MouseHorizontalPositionInPixels, ActualHeight));
    }
    this.AddVisualChild(MarkerVisual);

However, in this situation, the UIelements defined in xaml in the canvas are displayed, but not the marker drawingvisual.

Converting the Visual to a UIElement would allow a Panel.Children.Add ... so maybe add an Image with a RenderTargetBitmap , which in turn can contain DrawingVisual . So something like:

DrawingVisual MarkerVisual = new DrawingVisual();
Loaded += (sender, args) => {
    DrawingContext drawingContext = MarkerVisual.RenderOpen();
    drawingContext.DrawText(text, new Point(2, 2));
    drawingContext.Close();

    RenderTargetBitmap bmp = new RenderTargetBitmap(180, 180, 120, 96, PixelFormats.Pbgra32);
    bmp.Render(drawingVisual);

    Image image = new Image();
    image.Source = bmp;
    this.Children.Add(image);
};

Ultimately I decided that WPF does not want my canvas containing both uielements and its own visual collection. It's possible to take the Elements that were added to Children and place them in your own visual collection on the Loaded Event. However, the items I removed from Children to handle myself didn't seem to update automatically on changes, so most likely it's not trivial to do. It's far easier to just have a container element for all drawing visuals and just place that using grid.zindex like so:

             <Grid
                Grid.ZIndex="3"
                Grid.Row="0"
                Grid.RowSpan="2"
                Grid.Column="0"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                x:Name="dragSelectionGrid"
                Visibility ="Visible"
                >
                <Components:MarkerElement 
                  Grid.ZIndex="1"
                  VerticalAlignment="stretch"
                  HorizontalAlignment="stretch"
                  />
                <Canvas x:Name="dragSelectionCanvas"
                        Grid.ZIndex="2"
                        >
                  <Border 
                    x:Name="dragSelectionBorder"
                    BorderBrush="White"
                    BorderThickness="0"
                    CornerRadius="1"
                    Visibility="Collapsed"
                    />
                </Canvas>
              </Grid>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM