Tech Off Post

Single Post Permalink

View Thread: Problem drawing visuals and controls on canvas
  • User profile image
    anaximander

    What I have now is just rudimentary to get everthing working. The full functionality will come later. It will be like a drawing or CAD program. (Sorry for not saying exactly what it will do.) This is the XAML and derived class. drawingSurface is my instance of my DrawingCanvas class and is standard boiler plate:

    <Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:CanvasTester"
        Title="MainWindow" Height="350" Width="525">
        <DockPanel HorizontalAlignment="Stretch" Name="DockPanel1" VerticalAlignment="Stretch" >
            <local:DrawingCanvas  x:Name="drawingSurface" DockPanel.Dock="Bottom" Background="AliceBlue"  >
            </local:DrawingCanvas>
        </DockPanel>
    </Window>


    Public Class DrawingCanvas
        Inherits Canvas
    
        Private visuals As New List(Of Visual)()
        Private hits As New List(Of DrawingVisual)()
    
    
        Protected Overrides Function GetVisualChild(ByVal index As Integer) As Visual
            Return visuals(index)
        End Function
    
        Protected Overrides ReadOnly Property VisualChildrenCount() As Integer
            Get
                Return visuals.Count
            End Get
        End Property
    
        Public Sub AddVisual(ByVal visual As Visual)
            visuals.Add(visual)
            MyBase.AddVisualChild(visual)
            MyBase.AddLogicalChild(visual)
        End Sub
    
        Public Sub DeleteVisual(ByVal visual As Visual)
            visuals.Remove(visual)
            MyBase.RemoveVisualChild(visual)
            MyBase.RemoveLogicalChild(visual)
        End Sub
    
        Public Function GetVisual(ByVal point As Point) As DrawingVisual
            Dim hitResult As HitTestResult = VisualTreeHelper.HitTest(Me, point)
            Return TryCast(hitResult.VisualHit, DrawingVisual)
        End Function
    
        Public Function GetVisuals(ByVal region As Geometry) As List(Of DrawingVisual)
            hits.Clear()
            Dim parameters As New GeometryHitTestParameters(region)
            Dim callback As New HitTestResultCallback(AddressOf Me.HitTestCallback)
            VisualTreeHelper.HitTest(Me, Nothing, callback, parameters)
            Return hits
        End Function
    
        Private Function HitTestCallback(ByVal result As HitTestResult) As HitTestResultBehavior
            Dim geometryResult As GeometryHitTestResult = CType(result, GeometryHitTestResult)
            Dim visual As DrawingVisual = TryCast(result.VisualHit, DrawingVisual)
            If visual IsNot Nothing AndAlso geometryResult.IntersectionDetail = IntersectionDetail.FullyInside Then
                hits.Add(visual)
            End If
            Return HitTestResultBehavior.Continue
        End Function
    End Class
    


    Here is the main code that will have the functionality:

    Imports System.Globalization
    Class MainWindow
        Public visRectangle As DrawingVisual
        Private brTomato As Brush = Brushes.Tomato
        Private pen As Pen = New Pen(Brushes.SteelBlue, 3)
    
        Public Sub New()
            InitializeComponent()
            ' Draw a sample visual.
            Using dc As DrawingContext = visRectangle.RenderOpen
                dc.DrawRectangle(brTomato, pen, New Rect(20, 20, 50, 50))
            End Using
            drawingSurface.AddVisual(visRectangle)
    
            ' Draw a textbox.
            Dim tb As TextBox = New TextBox
            Dim brush As Brush = Brushes.Black
            Dim drawingPen As Pen = New Pen(Brushes.Green, 3)
            tb.Text = "Doh!"
            tb.Name = "someBox"
            Canvas.SetTop(tb, 10)
            Canvas.SetLeft(tb, 10)
            tb.Background = System.Windows.Media.Brushes.AliceBlue
            drawingSurface.Children.Add(tb)
        End Sub
    End Class