Group: Forum Members
Last Active: 6 Months Ago
Posts: 60,
Visits: 157
|
NChartControls fire MouseLeave and MouseEnter events after every MouseMove event when NChartControl.Settings.RenderSurface = window. Is there any way to prevent this behavior? Run the following example to reproduce the issue. Public Class MouseEventsForm Inherits Windows.Forms.Form
Private WithEvents _ChartControl1 As Nevron.Chart.WinForm.NChartControl Private WithEvents _CheckBox1 As Windows.Forms.CheckBox Private WithEvents _CheckBox2 As Windows.Forms.CheckBox Private WithEvents _TextBox1 As Windows.Forms.TextBox
Public Sub New() Me.Size = New Drawing.Size(1200, 824) Me.StartPosition = FormStartPosition.CenterScreen
Dim chart As New Nevron.Chart.NCartesianChart chart.Enable3D = True chart.Projection.SetPredefinedProjection(Nevron.GraphicsCore.PredefinedProjection.Orthogonal) Call AddLineSeries(250, 0.5#, Drawing.Color.Black, chart)
Dim chartBounds As New Drawing.Rectangle(0, 0, Me.ClientSize.Width - 300, Me.ClientSize.Height - 24) Me._ChartControl1 = New Nevron.Chart.WinForm.NChartControl Me._ChartControl1.Charts.Clear() Me._ChartControl1.Charts.Add(chart) Me._ChartControl1.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Or AnchorStyles.Bottom Me._ChartControl1.Bounds = chartBounds Me._ChartControl1.Settings.JitterMode = Nevron.Chart.JitterMode.Disabled Me._ChartControl1.Settings.RenderSurface = Nevron.GraphicsCore.RenderSurface.Window ' Me.Controls.Add(Me._ChartControl1)
Me._CheckBox1 = New Windows.Forms.CheckBox Me._CheckBox1.Text = "Render to Window" Me._CheckBox1.Location = New Drawing.Point(0, Me._ChartControl1.Bottom) Me._CheckBox1.AutoSize = True Me._CheckBox1.Anchor = AnchorStyles.Left Or AnchorStyles.Bottom Me._CheckBox1.Checked = (Me._ChartControl1.Settings.RenderSurface = Nevron.GraphicsCore.RenderSurface.Window) Me.Controls.Add(Me._CheckBox1)
Me._CheckBox2 = New Windows.Forms.CheckBox Me._CheckBox2.Text = "Include MouseMove Events" Me._CheckBox2.Location = New Drawing.Point(Me._CheckBox1.Right + 4, Me._ChartControl1.Bottom) Me._CheckBox2.AutoSize = True Me._CheckBox2.Anchor = AnchorStyles.Left Or AnchorStyles.Bottom Me._CheckBox2.Checked = False Me.Controls.Add(Me._CheckBox2)
Me._TextBox1 = New Windows.Forms.TextBox Me._TextBox1.Text = "" Me._TextBox1.Multiline = True Me._TextBox1.MaxLength = System.Int32.MaxValue Me._TextBox1.Bounds = New Drawing.Rectangle(Me._ChartControl1.Right + 4, Me._ChartControl1.Top, Me.ClientSize.Width - (Me._ChartControl1.Right + 4), Me._ChartControl1.Height) Me._TextBox1.ScrollBars = ScrollBars.Both Me._TextBox1.Anchor = AnchorStyles.Right Or AnchorStyles.Top Or AnchorStyles.Bottom Me.Controls.Add(Me._TextBox1) End Sub Private Sub AddLineSeries( _ ByVal count As Integer, _ ByVal phaseOffset As Double, _ ByVal color As Drawing.Color, _ ByVal chart As Nevron.Chart.NCartesianChart)
Dim series As New Nevron.Chart.NLineSeries series.DataLabelStyle.Visible = False series.BorderStyle.Color = color series.BorderStyle.Width = New Nevron.GraphicsCore.NLength(2.5!) ' Call Me.AddLineData(count, phaseOffset, series)
chart.Series.Add(series) End Sub Private Sub AddLineData( _ ByVal count As Integer, _ ByVal phaseOffset As Double, _ ByVal series As Nevron.Chart.NLineSeries)
Dim prevYVal As Double = 0 Dim prevXVal As Double = 0
Dim valueCount As Integer = series.Values.Count
If valueCount > 0 Then prevYVal = CDbl(series.Values(valueCount - 1)) prevXVal = CDbl(series.XValues(valueCount - 1)) End If
Dim xValues As Double() = New Double(count - 1) {} Dim yValues As Double() = New Double(count - 1) {}
Const constValue As Double = 0.5# 'Replaces the random value from the example. Dim magnitude As Double = 0.01 + constValue * 5
' continuous Dim angle As Double = 2 * Math.PI * phaseOffset Dim phase As Double = 10 * (Math.PI * 2 * constValue) / count + 0.0001
Dim i As Integer = 0 Do While i < count Dim yStep As Double = Math.Sin(angle) * magnitude Dim xStep As Double = 0.01 + constValue * magnitude
If xStep < 0 Then xStep = 0 End If
angle += phase prevXVal += xStep
yValues(i) = prevYVal + yStep xValues(i) = prevXVal i += 1 Loop
series.Values.AddRange(yValues) series.XValues.AddRange(xValues) End Sub
Private Sub _CheckBox1_CheckedChanged(sender As Object, e As System.EventArgs) Handles _CheckBox1.CheckedChanged If (Me._TextBox1 IsNot Nothing) Then Me._TextBox1.Text = "" End If If (Me._CheckBox1.Checked) Then Me._ChartControl1.Settings.RenderSurface = Nevron.GraphicsCore.RenderSurface.Window Else Me._ChartControl1.Settings.RenderSurface = Nevron.GraphicsCore.RenderSurface.Bitmap End If End Sub
Private Sub _ChartControl1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles _ChartControl1.MouseDown Static cnt As Integer : cnt += 1 Call Me.AddMessage(System.String.Format("{0} MouseDown", cnt.ToString("000"))) End Sub Private Sub _ChartControl1_MouseEnter(sender As Object, e As System.EventArgs) Handles _ChartControl1.MouseEnter Static cnt As Integer : cnt += 1 Call Me.AddMessage(System.String.Format("{0} MouseEnter", cnt.ToString("000"))) End Sub Private Sub _ChartControl1_MouseLeave(sender As Object, e As System.EventArgs) Handles _ChartControl1.MouseLeave Static cnt As Integer : cnt += 1 Call Me.AddMessage(System.String.Format("{0} MouseLeave", cnt.ToString("000"))) End Sub Private Sub _ChartControl1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles _ChartControl1.MouseMove Static cnt As Integer : cnt += 1 If (Me._CheckBox2.Checked) Then Call Me.AddMessage(System.String.Format("{0} MouseMove", cnt.ToString("000"))) End If End Sub Private Sub _ChartControl1_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles _ChartControl1.MouseUp Static cnt As Integer : cnt += 1 Call Me.AddMessage(System.String.Format("{0} MouseUp", cnt.ToString("000"))) End Sub
Private Sub AddMessage(ByVal message As String) If (Me._TextBox1.Text = "") Then Me._TextBox1.Text = message Else Me._TextBox1.Text = message & System.Environment.NewLine & Me._TextBox1.Text End If End Sub
End Class
|
Group: Forum Members
Last Active: Last Week
Posts: 3,054,
Visits: 4,009
|
Hi Lance, Thank you for pointing out this problem. It turns out windows forms generates mouse enter / leave events for every mouse move which occurs in the hardware accelerated inner window of the control. We've implemented a workaround for this behavior and will publish a SP today or tomorrow. You can then test it and check whether it fixes the problem.
Best Regards, Nevron Support Team
|
Group: Forum Members
Last Active: 6 Months Ago
Posts: 60,
Visits: 157
|
The extra MouseLeave and MouseEnter events do not occur in build 16.5.9.12 so thank you for the quick response.
NChartControl.OnMouseLeave and NChartControl.OnMouseEnter are still being called after every MouseMove event when the NChartControl is rendering to a window. I've implemented a workaround to account for this behavior so its not an issue at this time, but ideally those methods would only be called when appropriate.
|
Group: Forum Members
Last Active: Last Week
Posts: 3,054,
Visits: 4,009
|
Hi Lance, Those two methods are called from WinForms - we've also overridden them to filter unwanted Enter/Leave events. The workaround we used was: protected override void OnMouseLeave(EventArgs e) { // This is required because when in window mode mouse leave enter is called on every mouse move Point mousePosition = Control.MousePosition; NWin32.RECT rect = new NWin32.RECT(); NUser32.GetWindowRect(this.Handle, ref rect); Rectangle windowRect = new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); if (!windowRect.Contains(mousePosition)) { m_MouseIsOver = false; base.OnMouseLeave(e); if (m_View != null) { m_View.Controller.OnMouseLeave(this, e); } } } protected override void OnMouseEnter(EventArgs e) { // This is required because when in window mode mouse leave enter is called on every mouse move if (!m_MouseIsOver) { m_MouseIsOver = true; base.OnMouseEnter(e); if (m_View != null) { m_View.Controller.OnMouseEnter(this, e); } } }
probably you did something similar...
Best Regards, Nevron Support Team
|
Group: Forum Members
Last Active: 6 Months Ago
Posts: 60,
Visits: 157
|
Yes, I did something similar. Thanks for sharing your code!
|