-
September 15th, 2021, 02:38 AM
#1
Mixing StreamGeometry with Shapes
Hello,
I'm trying to replicate in wpf an old application builded with other tech. I need to draw a line chart with data loaded from a binary file, and then add a "select effect" with mouse.
I made 2 app to test the code: one for draw the chart using StramGeometry and one for draw a blue rectangle when click and over the mouse. They work both, but when I put all together, the rectangle is shown only before I draw the char then I never show up.
Here the code that I've tryed:
Code:
<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:
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
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|