I have a large, complex Windows Forms app written in VB.Net. Users are experiencing some memory issues and using JetBrains dotTrace Profiler to try and clear a few of these up.
There is still something holding some of my objects open. I have a 'Customer' object, which has a Generic.List of InvoiceLineItem. This item is basically an object bound to a grid control (ConponentOne FlexGrid) which has a load of readonly properties for displaying data, for example:
Public Class InvoiceLineItem
Private _customer as Customer
Private _charge as Charge
Sub New(Customer as Customer, Charge as Charge)
_customer = Customer
_charge = Charge
End Sub
Public ReadOnly Property Name as String
Return _customer.Name
End Property
Public ReadOnly Property ItemName as String
Return _charge.Name
End Property
Public ReadOnly Property Amount as Decimal
Return _charge.Amount
End Property
End Class
etc.
This object looks like it is not getting released from the FlexGrid.
The Flexgrid is on child form, shown from the main form. When the child form is closed, the Memory Profiler is showing that the form is still referenced.When I click "shortest Path" in dotTrace, the path below is shown.
This appears to be the only object in Customer with a root path.
There is no custom event handling going on in this form between my object or collection, and nothing is disposed.
What should I do to troubleshoot this further?
I found the issue. The FormClosing event was being handled elsewhere and tested for unsaved data, the reference to the form was being held in that function and not released!
Related
After breaking down all possible causes of the issue, I have arrived with the following situation. I have a custom user control containing a panel and a control (button, label etc...) within this panel. I have also created public read only properties for the panel as well as the child control of the panel. Each of these properties has their DesignerSerializationVisibility attribute set to Content. When configured this way no code is serialized for the child control of the panel when the custom user control is used on a form. Upon building the control, the child control either disappears or experiences an incomplete rendering at design-time. If I change either the panel or its child control’s DesignerSerializationVisibility to visible, everything serializes and renders correctly. However, this then prevents me from being able to provide the end user with the ability to adjust either the panel or child controls property values. This one truly has me stumped!
UPDATE:
After getting home and performing the same steps on my development VM (also a fresh installation of VS2013) there are no issues. I am very confused at why this issue would be occurring on my work computer and not another. Any ideas are greatly appreciated as the mystery deepens...
Public Class ExampleUserControl
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
<Browsable(True), _
EditorBrowsable(EditorBrowsableState.Always), _
Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public ReadOnly Property LeftPanel As Panel
Get
Return Me.ExampleLeftPanel
End Get
End Property
<Browsable(True), _
EditorBrowsable(EditorBrowsableState.Always), _
Category("Control"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public ReadOnly Property LeftPanelButton As Button
Get
Return Me.ExampleLeftButton
End Get
End Property
<Browsable(True), _
EditorBrowsable(EditorBrowsableState.Always), _
Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public ReadOnly Property RightPanel As Panel
Get
Return Me.ExampleRightPanel
End Get
End Property
<Browsable(True), _
EditorBrowsable(EditorBrowsableState.Always), _
Category("Control"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public ReadOnly Property RightPanelButton As Button
Get
Return Me.ExampleRightButton
End Get
End Property
End Class
I'm still not sure why this issue was occurring. However, after moving the custom user control into my control library (a separate .dll), all is working as expected. I suspect it was a glitch in the timing when compiling. Possibly it was trying to build the controls and serialize the code at the same time.
I have the following lines of code as a test user control. When the project is built, and I drag this user control onto a form, I get an error dialogue to the effect that EF can't find the connection string for the context. Yet when I use the same variable in a form, all is well. It seems the user control is using a different context within which to look for the connection string than the usual app.config.
Public Class InvoiceWorkOrderSearch
Private _dataHelper As WorkOrderData = New WorkOrderData()
End Class
During Design time?
You can avoid this be only instancing the object if the control is in runtime mode.
The build in property to check for desing time (Me.DesignMode) is poor since it only tells you if you are currently designing the control itself. It returs false if you drop the usercontrol on a form.
You can use this code to check for designtime: http://dotnet-snippets.de/dns/designmode-workaround-windows-forms-SID299.aspx
Public Class InvoiceWorkOrderSearch
Private _dataHelper As WorkOrderData
Public Sub New()
If IsDesignMode(me) = False Then
_dataHelper = New WorkOrderData()
End If
End Sub()
End Class
please see image attached.
i want it to be
Public components As System.ComponentModel.lContainer
but every time I edit the form design, it always change back to its original code
Private components As System.ComponentModel.lContainer
You can have a public Property in your class that returns a private member, like yours. This code is generated by form designer and probably you can not change the behavior of this. Even if you could, I wouldn't suggest you to do this.
Public Class MyForm
Public Property Container As System.ComponentModel.IContainer
Get
Return Me.components
End Get
End Property
End Class
Cheers
I'm trying to create a control (Parent Class) that uses a custom grid (Child Class). The grid has a series of constructors and methods for populating itself based on property values in the [parent] control.
The only way I found to make these property values available to the grid is by making them Shared but that's causing me all kinds of issues.
REQUIREMENTS
Properties in the control (parent) must be accessible to the grid (child).
Properties in the control must be visible in the design-time properties explorer.
The grid class must only be instantiable by the parent class.
As a side note: please indicate if your answer will allow me to share properties/methods back and forth between child and parent. That would be nice, but just a bonus.
Thanks ;)
EDIT - A VERY simple example based on my situation:
Partial Public Class catContent
Inherits System.Web.UI.UserControl
Protected Sub Page_Load(sender, e) Handles Me.Load
Page.Controls.Add(New CategoryResultGrid(category))
End Sub
Private Shared _product As String = String.Empty
Shared Property Product() As String
Get
Return _product
End Get
Set(ByVal value As String)
_product = value.Trim()
End Set
End Property
Private Class CategoryResultGrid
Inherits GridView
Sub New(ByVal category As String)
'How do I access "Product" here without sharing it?
End Sub
End Class
End Class
Do NOT use shared, it will break your app as soon as you put more than one of you custom control in your app.
If you only want the Grid to exist in the context of the Parent control, then consider exposing it similar to how the ListView control exposes its Items collection.
If you want your Grid to access fields in the (parent) Control there are several ways to do that. You could pass an instance of the Parent to the Grid, you can let the Grid use the standard Control methods to get its parent reference, or you can implement the Grid as an inner class of the Parent.
I'm having some issues and it's all explained in some simplified code
I have a structure
Public Structure myStruct
Public Property name As String
Public Property span As Double
Public Property offs As Double
End Structure
Which is instantiated in a Singleton object as follow
Public myValues(10) As myStruct
Then on a form, I'm using the structure as the DataSource for a SourceBinder and the binder as DataSource for a DataGridView.
On loading the form, I get all the values into the binder
For i As Integer = 0 To 9
binder.Add(singleton.getRef.myValues(i))
Next i
All the values are shown on the grid.
User is supposed to be able to change the values, which should reflect on myValues but no matter, what code I put on CellValueChanged or CurrentChanged. I can't make it reflect the changes.
Using breakbpoints on those events, I noticed that grid.row().cell().values and binder.current never changes.
I tried also placing a button and directly changing myValues and reseting the binder binder.ResetBindings(False) and nothing happens.
As far as I saw all ReadOnly properties are set to false.
I've also tried setting VirtualMode to true on the grid and catching CellValuePushed and CellValueNeeded events but those are never called. (that was on a guessing base)
I'm really out of ideas on this one, if anyone can help me!
thanks.
Try using a class instead:
Public Class myStruct
Public Property name As String
Public Property span As Double
Public Property offs As Double
End Class