简体   繁体   English

如何在XAML中定义的Canvas的子UIElement上方的画布上显示drawingvisual

[英]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. 因此,我在来自画布的类中的VisualCollection视觉对象中有一个drawingvisual标记。

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. 在xaml中,我定义了一个拖动选择边框,希望也可以绘制它。

             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? 通常,我会覆盖它们,但是是否必须在xaml中定义画布的所有子项并将它们添加到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. 如果我只是重写这两个方法,则在render调用getvisualchild时,它仅绘制标记DrawingVisual,但不会获取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. 我想也许我可以使用Panel.Children.Add,但是它需要一个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. 然后,我认为也许正确的方法只是Visual.AddVisualChild,所以我在Canvas中的set marker事件上运行了此代码。

    {
    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. 但是,在这种情况下,将显示画布中以xaml定义的UIelements,而不显示标记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 . 将Visual转换为UIElement将允许Panel.Children.Add ...,所以也许添加一个带有RenderTargetBitmapImage ,该Image又可以包含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. 最终,我决定WPF不想让我的画布同时包含uielements和它自己的视觉集合。 It's possible to take the Elements that were added to Children and place them in your own visual collection on the Loaded Event. 可以将添加到Children中的Elements并将其放置在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.zindex像这样放置它要容易得多:

             <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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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