mixing StreamGeometry and shapes

Damien.darhk

Member
Joined
Aug 13, 2021
Messages
9
Programming Experience
3-5
I'm drawing a chart from a binary file with StreamGeometry, and work fine; I need to do a "selection effect" so I tryed to add the code that I have tested alone that draw a semitrasparent rectangle clicking the mouse, but it have an odd behavier:
before to draw the chart(done by clicking the button), the effect work, but after the chart is drawed it not work anymore. any advice?(for test the code you can use any file, it doesn't matter).

xaml:
<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:testwpf2d"
        mc:Ignorable="d"
        Title="MainWindow" Height="1080" Width="1920" SizeChanged="Window_SizeChanged">
    <Grid x:Name="BaseGrid" Loaded="BaseGrid_Loaded">



        <Canvas Height="856" Canvas.Left="212" Canvas.Top="126" Width="1496" Background="Black" x:Name="mycanvas" UseLayoutRounding="False" MouseDown="mycanvas_MouseDown" MouseUp="mycanvas_MouseUp" MouseMove="mycanvas_MouseMove" >
            <Rectangle x:Name="selectionBox"
                Visibility="Collapsed"
                Stroke="Black"
                StrokeThickness="1"
               Fill="Blue" Opacity="0.5"
                />
        </Canvas>
        <Button Content="Button" Canvas.Left="1755" Click="Button_Click" Margin="57,29,1490,895"/>
    </Grid>
 
</Window>


Code behind:
Imports Microsoft.Win32
Imports System.IO
Imports System.Math
Imports System
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Windows
Imports System.Windows.Input
Imports System.Windows.Shapes

Class MainWindow
    Public Shared MyArray As Byte()
    Private Sub BaseGrid_Loaded(sender As Object, e As RoutedEventArgs) Handles BaseGrid.Loaded
        Dim openFileDialogORI As OpenFileDialog = New OpenFileDialog()
        If openFileDialogORI.ShowDialog = True Then
            Try
                Dim MyFileORIStream As FileStream = New FileStream(openFileDialogORI.FileName, FileMode.Open, FileAccess.Read)
                Dim ORIBuffer As BinaryReader = New BinaryReader(MyFileORIStream)
                Dim fInfo As New FileInfo(openFileDialogORI.FileName)
                Dim numBytes As Long = fInfo.Length
                MyArray = ORIBuffer.ReadBytes(CInt(numBytes))
                ORIBuffer.Close()
                MyFileORIStream.Close()
                Dim NomeFileOri As String = openFileDialogORI.FileName
                Dim info As New FileInfo(openFileDialogORI.FileName)
                Dim length As Integer = CInt(info.Length)
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
        End If

    End Sub

    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        'cancella elenco punti
        mycanvas.Children.Clear()
        Dim Host As New VisualHost
        mycanvas.Children.Add(Host)
        Host.Draw()
        VisualHost.a = VisualHost.a + 30
    End Sub

    Private Sub Window_SizeChanged(sender As Object, e As SizeChangedEventArgs)
        BaseGrid.Width = e.NewSize.Width
        BaseGrid.Height = e.NewSize.Height
        Dim xChange As Double = 1, yChange As Double = 1
        If e.PreviousSize.Width <> 0 Then xChange = (e.NewSize.Width / e.PreviousSize.Width)
        If e.PreviousSize.Height <> 0 Then yChange = (e.NewSize.Height / e.PreviousSize.Height)

        For Each fe As FrameworkElement In BaseGrid.Children

            If TypeOf fe Is Grid = False Then
                fe.Height = fe.ActualHeight * yChange
                fe.Width = fe.ActualWidth * xChange
                Canvas.SetTop(fe, Canvas.GetTop(fe) * yChange)
                Canvas.SetLeft(fe, Canvas.GetLeft(fe) * xChange)
            End If
        Next
    End Sub
    Private mouseDownx As Boolean = False
    Private mouseDownPosx As Point

    Private Sub mycanvas_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles mycanvas.MouseUp
        mycanvas.ReleaseMouseCapture()
        selectionBox.Visibility = Visibility.Collapsed
        Dim mouseUpPos As Point = e.GetPosition(mycanvas)
    End Sub

    Private Sub mycanvas_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles mycanvas.MouseDown
        mouseDownx = True
        mouseDownPosx = e.GetPosition(mycanvas)
        mycanvas.CaptureMouse()
        mycanvas.SetLeft(selectionBox, mouseDownPosx.X)
        mycanvas.SetTop(selectionBox, mouseDownPosx.Y)
        selectionBox.Width = 0
        selectionBox.Height = 0
        selectionBox.Visibility = Visibility.Visible
    End Sub

    Private Sub mycanvas_MouseMove(sender As Object, e As MouseEventArgs) Handles mycanvas.MouseMove
        If mouseDownx Then
            Dim mousePos As Point = e.GetPosition(mycanvas)

            If mouseDownPosx.X < mousePos.X Then
                Canvas.SetLeft(selectionBox, mouseDownPosx.X)
                selectionBox.Width = mousePos.X - mouseDownPosx.X
            Else
                Canvas.SetLeft(selectionBox, mousePos.X)
                selectionBox.Width = mouseDownPosx.X - mousePos.X
            End If

            If mouseDownPosx.Y < mousePos.Y Then
                Canvas.SetTop(selectionBox, mouseDownPosx.Y)
                selectionBox.Height = mousePos.Y - mouseDownPosx.Y
            Else
                Canvas.SetTop(selectionBox, mousePos.Y)
                selectionBox.Height = mouseDownPosx.Y - mousePos.Y
            End If
        End If
    End Sub
End Class
Public Class VisualHost

    Inherits FrameworkElement

    Dim Visual As New DrawingVisual()
    Dim Context As DrawingContext
    Dim Pen As Pen
    Public Shared a As Integer = 0


    Dim rand As New Random

    Public Sub New()

        Pen = New Pen(Brushes.Red, 1)
        Pen.Freeze()
        SnapsToDevicePixels = True
        SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased)

        AddVisualChild(Visual)

    End Sub

    Public Sub Draw()

        Dim Geometry As New StreamGeometry()
        Geometry.Clear()
        Using GeometryContext As StreamGeometryContext = Geometry.Open()



            For i As Integer = 1 To 1000
                GeometryContext.BeginFigure(New Point(i * 5, MainWindow.MyArray(i + a)), False, False)
                GeometryContext.LineTo(New Point((i + 1) * 5, MainWindow.MyArray(i + 1 + a)), True, True)

            Next

        End Using

        Geometry.Freeze()

        Using Context = Visual.RenderOpen()
            Context.DrawGeometry(Nothing, Pen, Geometry)
        End Using

    End Sub

    Protected Overrides ReadOnly Property VisualChildrenCount() As Integer
        Get
            Return 1
        End Get
    End Property

    Protected Overrides Function GetVisualChild(index As Integer) As Visual
        Return Visual
    End Function

End Class
 
Last edited:
Back
Top