Fire Timer Tick from Baseform - vb.net

I have a base Form with a Timer that simply should show the time in all Forms that inherit from it.
MainForm (which inherits from BaseForm) does this job very well.
From MainForm, I open other Forms which inherit from Baseform.
In these Forms, the time won't change after the Form is opened.
The work is the same in all derived Forms. Each Timer Tick should update the Time in a Label in the active Form.
I have tried Property Binding and adding the event in each form. Nothing works properly.
I am thankful for any hint :-)
Here i have the code from my BaseForm
Partial Class FrmBasisNew
Inherits Form
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Wird vom Windows Form-Designer benötigt.
Private components As System.ComponentModel.IContainer
'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
'Das Bearbeiten ist mit dem Windows Form-Designer möglich.
'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(FrmBasisNew))
Me.Tim_Uhrzeit = New System.Windows.Forms.Timer(Me.components)
Me.PNLTOP = New System.Windows.Forms.Panel()
Me.lblTime = New System.Windows.Forms.Label()
Me.PNLTOP.SuspendLayout()
Me.SuspendLayout()
'
'Tim_Uhrzeit
'
Me.Tim_Uhrzeit.Interval = 1000
'
'PNLTOP
'
Me.PNLTOP.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.PNLTOP.BackColor = Global.KundF.My.MySettings.Default.glUserDefinedBackColor
Me.PNLTOP.Controls.Add(Me.lblTime)
Me.PNLTOP.Dock = System.Windows.Forms.DockStyle.Top
Me.PNLTOP.Location = New System.Drawing.Point(0, 0)
Me.PNLTOP.Margin = New System.Windows.Forms.Padding(0)
Me.PNLTOP.Name = "PNLTOP"
Me.PNLTOP.Size = New System.Drawing.Size(788, 58)
Me.PNLTOP.TabIndex = 2
'
'lblTime
'
Me.lblTime.DataBindings.Add(New System.Windows.Forms.Binding("Text", Global.KundF.My.MySettings.Default, "glUserdefinedTime", True, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged))
Me.lblTime.Dock = System.Windows.Forms.DockStyle.Right
Me.lblTime.Font = New System.Drawing.Font("Microsoft Sans Serif", 15.75!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.lblTime.ForeColor = System.Drawing.SystemColors.ActiveCaptionText
Me.lblTime.Location = New System.Drawing.Point(724, 0)
Me.lblTime.Name = "lblTime"
Me.lblTime.Size = New System.Drawing.Size(64, 58)
Me.lblTime.TabIndex = 6
Me.lblTime.Text = Global.KundF.My.MySettings.Default.glUserdefinedTime
'
'FrmBasisNew
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(788, 716)
Me.ControlBox = False
Me.Controls.Add(Me.PNLTOP)
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.Name = "FrmBasisNew"
Me.ShowIcon = False
Me.ShowInTaskbar = False
Me.WindowState = System.Windows.Forms.FormWindowState.Maximized
Me.PNLTOP.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
Friend WithEvents PNLTOP As Panel
Protected WithEvents Tim_Uhrzeit As Timer
Friend WithEvents lblTime As Label
End Class
Then the Code for The BaseForm
Public Class FrmBasisNew
Private Sub Tim_Uhrzeit_Tick(sender As Object, e As EventArgs) Handles Tim_Uhrzeit.Tick
SetTime()
End Sub
Public Overridable Sub SetTime()
Me.lblTime.Text = Format(Now, "hh:mm:ss").ToString
End Sub
End Class
Now, the DesignerCode for my Mainform

Related

add button to TreeNode

Good day.
There is a custom control that adds a button to each Node
Imports System.Windows.Forms.VisualStyles
Public Class CustomTreeView
Inherits TreeView
Private buttonRect As New Rectangle(80, 2, 50, 26)
Private ReadOnly stringFormat As StringFormat
Public Sub New()
SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
DrawMode = TreeViewDrawMode.OwnerDrawText
ShowLines = False
FullRowSelect = True
ItemHeight = 30
stringFormat = New StringFormat With {
.Alignment = StringAlignment.Near,
.LineAlignment = StringAlignment.Center
}
End Sub
Protected Overrides Sub OnDrawNode(ByVal e As DrawTreeNodeEventArgs)
e.Graphics.DrawString(e.Node.Text, Me.Font, New SolidBrush(Me.ForeColor), e.Bounds, stringFormat)
ButtonRenderer.DrawButton(e.Graphics, New Rectangle(e.Node.Bounds.Location + New Size(buttonRect.Location), buttonRect.Size), "btn", Me.Font, True, If(e.Node.Tag IsNot Nothing, CType(e.Node.Tag, PushButtonState), PushButtonState.Normal))
End Sub
Protected Overrides Sub OnNodeMouseClick(ByVal e As TreeNodeMouseClickEventArgs)
Select Case e.Node.Tag
Case Nothing, Is <> PushButtonState.Pressed
Return
End Select
e.Node.Tag = PushButtonState.Normal
MessageBox.Show(e.Node.Text & " clicked")
' force redraw
e.Node.Text = e.Node.Text
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
Dim tnode As TreeNode = GetNodeAt(e.Location)
If tnode Is Nothing Then
Return
End If
Dim btnRectAbsolute As New Rectangle(tnode.Bounds.Location + New Size(buttonRect.Location), buttonRect.Size)
If btnRectAbsolute.Contains(e.Location) Then
tnode.Tag = PushButtonState.Pressed
tnode.Text = tnode.Text
End If
End Sub
End Class
tell me how you can display the button only to the first (main) nod?
And how, when you click on this button, not display a message, but let's say call some procedure?
There is no built-in button tree node. But you can create a custom tree node having a button yourself. This custom tree node inherits from TreeNode. To improve extensibility, we declare an interface for tree nodes having a DrawNode method:
Imports System.Windows.Forms.VisualStyles
Public Interface ICustomDrawTreeNode
Sub DrawNode(ByVal e As DrawTreeNodeEventArgs, buttonState As PushButtonState)
End Interface
We also create a module containing some settings used in the custom tree view and in the custom tree node
Module Settings
Public ReadOnly ButtonRect As New Rectangle(80, 2, 50, 26)
Public ReadOnly TextStringFormat = New StringFormat() With {
.Alignment = StringAlignment.Near,
.LineAlignment = StringAlignment.Center,
.FormatFlags = StringFormatFlags.NoClip Or StringFormatFlags.FitBlackBox Or StringFormatFlags.LineLimit
}
End Module
We can then implement a button node like this
Imports System.Windows.Forms.VisualStyles
Public Class ButtonTreeNode
Inherits TreeNode
Implements ICustomDrawTreeNode
Private ReadOnly buttonText As String
Public Sub New(text As String, buttonText As String)
MyBase.New(text)
Me.buttonText = buttonText
End Sub
Public Sub DrawNode(e As DrawTreeNodeEventArgs, buttonState As PushButtonState) _
Implements ICustomDrawTreeNode.DrawNode
Dim font As Font = e.Node.TreeView.Font
' Draw Text to the left of the button
Dim rect As Rectangle = New Rectangle(
e.Node.Bounds.Location,
New Size(Settings.ButtonRect.Left, e.Bounds.Height))
e.Graphics.DrawString(e.Node.Text, font, Brushes.Black, rect, Settings.TextStringFormat)
' Draw the button
rect = New Rectangle(
e.Node.Bounds.Location + Settings.ButtonRect.Location,
Settings.ButtonRect.Size)
ButtonRenderer.DrawButton(e.Graphics, rect, buttonText, font, True, buttonState)
End Sub
End Class
It has a Private ReadOnly buttonText As String to store the text of the button. The normal node text and the button text are passed in the constructor of ButtonTreeNode:
Public Sub New(text As String, buttonText As String)
The DrawNode method will be called be the CustomTreeView in OnDrawNode.
In CustomTreeView I declared a NodeButtonClick event that will be raised when the button of a node is clicked. You can then handle this event in the form. When you select the CustomTreeView in the designer, this new event will appear in the "Action" section of the events.
Imports System.ComponentModel
Imports System.Windows.Forms.VisualStyles
Public Class CustomTreeView
Inherits TreeView
<Category("Action")>
Public Event NodeButtonClick(e As TreeNodeMouseClickEventArgs)
Private _isButtonPressed As Boolean
Public Sub New()
SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
DrawMode = TreeViewDrawMode.OwnerDrawText
ShowLines = False
FullRowSelect = True
ItemHeight = 30
End Sub
Protected Overrides Sub OnDrawNode(e As DrawTreeNodeEventArgs)
Dim customDrawNode As ICustomDrawTreeNode = TryCast(e.Node, ICustomDrawTreeNode)
If customDrawNode Is Nothing Then ' Normal text node.
e.Graphics.DrawString(e.Node.Text, Font, Brushes.Black, e.Node.Bounds, Settings.TextStringFormat)
Else
customDrawNode.DrawNode(e, If(_isButtonPressed, PushButtonState.Pressed, PushButtonState.Normal))
End If
End Sub
Protected Overrides Sub OnNodeMouseClick(e As TreeNodeMouseClickEventArgs)
If _isButtonPressed Then
_isButtonPressed = False
Refresh()
Dim buttonNode = TryCast(e.Node, ButtonTreeNode)
If buttonNode IsNot Nothing Then
RaiseEvent NodeButtonClick(e)
End If
End If
End Sub
Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
Dim buttonNode = TryCast(GetNodeAt(e.Location), ButtonTreeNode)
If buttonNode IsNot Nothing Then
Dim btnRectAbsolute As New Rectangle(
buttonNode.Bounds.Location + Settings.ButtonRect.Location,
Settings.ButtonRect.Size)
_isButtonPressed = btnRectAbsolute.Contains(e.Location)
If _isButtonPressed Then
Refresh()
End If
End If
End Sub
End Class
In the form you can write
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TreeView1.Nodes.Add("Text")
TreeView1.Nodes.Add(New ButtonTreeNode("Caption", "Button"))
End Sub
Private Sub TreeView1_NodeButtonClick(e As TreeNodeMouseClickEventArgs) _
Handles TreeView1.NodeButtonClick
MessageBox.Show(e.Node.Text & " clicked")
End Sub
End Class
This adds a normal text node and a custom button node to the TreeView. It also handles the NodeButtonClick of the custom TreeView.

Resize ToolStrip Button Image programatically at startup via toolstrip.ImageScalingSize

So I've read around this and will provide relevant properties at the end.
I'm looking to store a custom ToolStrip button image size in my.settings and load them at startup, changing them to a user set size.. The code I run at startup is:
Dim tss As New List(Of ToolStrip)
tss = GetAllControls(Me).OfType(Of ToolStrip)().ToList
For Each ts In tss
ts.BackColor = My.Settings.ToolStripBGColor
ts.ImageScalingSize = New Size(My.Settings.ToolStripImgScalingSize, My.Settings.ToolStripImgScalingSize)
ts.ResumeLayout()
ts.Invalidate()
ts.Refresh()
Next
ToolStripContainer.Invalidate()
ToolStripContainer.Refresh()
This does change the properties of all of the ToolStips. However, the images initially display at the default 16x16 UNTIL I drag them into another area of the ToolStripContainer. It then resizes correctly. This tends to imply to me that it's something to so with the draw of these containers/controls (hence the blanket bombing of .invalidate, .resumelayout and .refresh!)
Regarding proprieties, the relevant ones within designer view:
ToolStripButton
.autosize = true
.imagescaling = SizeToFit
ToolStrip
.autosize = true
.imagesclaing = 16,16 (later modified by code)
ToolStripContainer
couldn't see any that would effect this!??
This is one of those where you go round in circles for half a day over what essentially could be due to a janky aspect of .net! Could be me though...
Getting this to work with AutoSize=True is always a bit confusing. I've found that if you set it to False with layout suspended and then set it to True with layout enabled, that you can get the desired effect.
That description is probably clear as mud, so here is the code pattern.
With ToolStrip1
.SuspendLayout()
.AutoSize = False
.ImageScalingSize = New Size(40, 40)
.ResumeLayout()
.AutoSize = True
End With
Imports System.Drawing : Imports Microsoft.VisualBasic
Imports Microsoft.Win32 : Imports System
Imports System.IO : Imports System.Windows.Forms
Public Class Form1
Inherits Form
Private toolStripItem1 As ToolStripButton
Private toolStrip1 As ToolStrip
Public Sub New()
toolStrip1 = New System.Windows.Forms.ToolStrip()
toolStrip1.Size = New System.Drawing.Size(580,40)
toolStrip1.BackColor = System.Drawing.Color.MistyRose
toolStrip1.AutoSize = True
toolStripItem1 = New System.Windows.Forms.ToolStripButton()
toolStrip1.SuspendLayout()
Me.SuspendLayout()
toolStrip1.Items.AddRange(New System.Windows.Forms.ToolStripButton() _
{toolStripItem1})
toolStrip1.Location = New System.Drawing.Point(0, 0)
toolStrip1.Name = "toolStrip1"
toolStripItem1.AutoSize = False
toolStripItem1.Size = New System.Drawing.Size(110,95)
toolStripItem1.BackgroundImage = Image.FromFile("D:\Book4\Resources\icos\CUT.png")
toolStripItem1.Name = "toolStripItem1"
toolStripItem1.Text = "Cut"
toolStripItem1.Font = New System.Drawing.Font("Segoe UI", 16.0!, _
System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, _
CType(0, Byte))
toolStripItem1.TextAlign = System.Drawing.ContentAlignment.TopCenter
AddHandler Me.toolStripItem1.Click, New System.EventHandler _
(AddressOf Me.toolStripItem1_Click)
Me.AutoScaleDimensions = New System.Drawing.SizeF(6F, 13F)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(1500,900)
Me.BackColor = ColorTranslator.FromHtml("#808080")
Me.Controls.Add(Me.toolStrip1)
Me.Name = "Form1"
toolStrip1.ResumeLayout(False)
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Public Sub Form1_Loaded(sender As Object, e As EventArgs) _
Handles MyBase.Load
Try
Dim ico As New System.Drawing.Icon("D:\Resources\icos\kvr.ico")
Me.Icon = ico
Catch ex As Exception
End Try
End Sub
Public Shared Sub Main()
Dim form1 As Form1 = New Form1()
form1.ShowDialog()
End Sub
Private Sub toolStripItem1_Click(ByVal sender As Object,ByVal e As EventArgs)
System.Windows.Forms.MessageBox.Show("Successfully enlarged ToolStripButtonImage size")
End Sub
End Class

Using IMAP in VB.Net to retrieve Mails from MS Exchange Server

I am referring to a previous post somewhere in the past (cf. Hyperlink). I could not add any comments, nor did I consider writing a reply since my Problem differs slightly. Please excuse if I posted in the wrong section or for opening a new thread on this topic, I am still new to this Forum.
Please let me illustrate the following issue: Similar to this post, I would like to access and retrieve emails and attachments from a MS Exchange Server. I mainly used the code provided by in the Hyperlink above, but I could not connect to the mail Server (I used port 587). In my opinion there was a successful Connection, but the code stops when reaching the following line
Dim Read_Stream2 = New StreamReader(Sstream)
Saying that the data stream could not be read.
I also have a question about this particular line, since I am unable to figure out why there is need to convert the NetworkStream into an SslStream and then into a StreamReader Object. Could somebody please explain this necessity?
As for the remaining Problem, please consider my code so far below. If it might be too cumbersome using IMAP, I would also welcome hints about how to achieve this goal using POP3.
Thanks a mil in advance for any help provided.
Imports System.Net.Sockets
Imports System.IO
Imports System.Text
Imports System.Net.Security
Public Class emailDownloader
Dim ServerNm As String
Dim UsrNm As String
Dim PassStr As String
Dim _IntPort As Integer
Dim ImapClient As New Net.Sockets.TcpClient
Dim NetworkS_stream As NetworkStream
Dim m_sslStream As SslStream
Dim Read_Stream As StreamReader
Dim StatResp As String
Dim m_buffer() As Byte
Function Login(ByVal Sstream As SslStream, ByVal Server_Command As String)
ImapClient = New TcpClient(ServerNm, _IntPort)
NetworkS_stream = ImapClient.GetStream 'Read the stream
Sstream = New SslStream(NetworkS_stream)
Dim Read_Stream2 = New StreamReader(Sstream)
Server_Command = Server_Command ' + vbCrLf
m_buffer = System.Text.Encoding.ASCII.GetBytes(Server_Command.ToCharArray())
Sstream.Write(m_buffer, 0, m_buffer.Length)
Dim Server_Reponse As String
Server_Reponse = Read_Stream2.ReadLine()
Return Server_Reponse
End Function
Private Sub btnStart_Click(sender As System.Object, e As System.EventArgs) Handles btnStart.Click
lbMailsRetrieved.Items.Clear()
ServerNm = tbServerName.Text
_IntPort = tbPortName.Text
UsrNm = tbUserName.Text
PassStr = tbPasswort.Text
StatResp = Login(m_sslStream, "LOGIN " + UsrNm + " " + PassStr + " ") & vbCrLf
lbMailsRetrieved.Items.Add(StatResp)
End Sub
End Class
There was a solution initially programmed in C#, which can be found here. I modified the code a bit and it is working for exchange (and only that).
Imports Microsoft.Exchange.WebServices.Data
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading.Tasks
Imports System.Windows.Forms
Namespace ReadMailFromExchangeServer
Public Class Form1
Inherits Form
Private exchange As ExchangeService
Public Sub New()
InitializeComponent()
lstMsg.Clear()
lstMsg.View = View.Details
lstMsg.Columns.Add("Date", 150)
lstMsg.Columns.Add("From", 250)
lstMsg.Columns.Add("Subject", 400)
lstMsg.Columns.Add("Has Attachment", 50)
lstMsg.Columns.Add("Id", 100)
lstMsg.FullRowSelect = True
End Sub
Private Sub btnRead_Click(sender As Object, e As EventArgs) Handles btnRead.Click
ConnectToExchangeServer()
'Dim ts As New TimeSpan(0, -1, 0, 0)
'Dim [date] As DateTime = DateTime.Now.Add(ts)
'Dim filter As New SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, [date])
If exchange IsNot Nothing Then
Dim findResults As FindItemsResults(Of Item) = exchange.FindItems(WellKnownFolderName.Inbox, New ItemView(50))
'Original
'Dim findResults As FindItemsResults(Of Item) = exchange.FindItems(WellKnownFolderName.Inbox, filter, New ItemView(50))
For Each item As Item In findResults
Dim message As EmailMessage = EmailMessage.Bind(exchange, item.Id)
Dim listItem As New ListViewItem({message.DateTimeReceived.ToString(), _
message.From.Name.ToString() + _
"(" + message.From.Address.ToString() + ")", _
message.Subject, (If((message.HasAttachments), "Yes", "No")), _
message.Id.ToString()})
lstMsg.Items.Add(listItem)
Next
If findResults.Items.Count <= 0 Then
lstMsg.Items.Add("No Messages found!!")
End If
End If
End Sub
Public Sub ConnectToExchangeServer()
lblMsg.Text = "Connecting to Exchange Server.."
lblMsg.Refresh()
Try
exchange = New ExchangeService(ExchangeVersion.Exchange2007_SP1)
exchange.Credentials = New WebCredentials("abc", "xyz")
exchange.AutodiscoverUrl("efg")
lblMsg.Text = "Connected to Exchange Server : " + exchange.Url.Host
lblMsg.Refresh()
Catch ex As Exception
lblMsg.Text = "Error Connecting to Exchange Server!!" + ex.Message
lblMsg.Refresh()
End Try
End Sub
Private Sub btnLoadAttachment_Click(sender As Object, e As EventArgs) Handles btnLoadAttachment.Click
If exchange IsNot Nothing Then
If lstMsg.Items.Count > 0 Then
Dim item As ListViewItem = lstMsg.SelectedItems(0)
If item IsNot Nothing Then
Dim msgid As String = item.SubItems(4).Text.ToString()
Dim message As EmailMessage = EmailMessage.Bind(exchange, New ItemId(msgid))
If message.HasAttachments AndAlso TypeOf message.Attachments(0) Is FileAttachment Then
Dim fileAttachment As FileAttachment = TryCast(message.Attachments(0), FileAttachment)
'Change the below Path   
fileAttachment.Load("C:[my_path]" + fileAttachment.Name)
lblAttach.Text = "Attachment Downloaded : " + fileAttachment.Name
Else
MessageBox.Show("No Attachments found!!")
End If
Else
MessageBox.Show("Please select a Message!!")
End If
Else
MessageBox.Show("Messages not loaded!!")
End If
Else
MessageBox.Show("Not Connected to Mail Server!!")
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs)
End Sub
Private Sub InitializeComponent()
Me.btnRead = New System.Windows.Forms.Button()
Me.lstMsg = New System.Windows.Forms.ListView()
Me.btnLoadAttachment = New System.Windows.Forms.Button()
Me.lblMsg = New System.Windows.Forms.Label()
Me.label1 = New System.Windows.Forms.Label()
Me.lblAttach = New System.Windows.Forms.Label()
Me.SuspendLayout()
'
'btnRead
'
Me.btnRead.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None
Me.btnRead.FlatStyle = System.Windows.Forms.FlatStyle.Flat
Me.btnRead.Location = New System.Drawing.Point(39, 284)
Me.btnRead.Name = "btnRead"
Me.btnRead.Size = New System.Drawing.Size(174, 23)
Me.btnRead.TabIndex = 0
Me.btnRead.Text = "Read Mails"
Me.btnRead.UseVisualStyleBackColor = True
'
'lstMsg
'
Me.lstMsg.Location = New System.Drawing.Point(27, 70)
Me.lstMsg.Name = "lstMsg"
Me.lstMsg.Size = New System.Drawing.Size(664, 191)
Me.lstMsg.TabIndex = 1
Me.lstMsg.UseCompatibleStateImageBehavior = False
'
'btnLoadAttachment
'
Me.btnLoadAttachment.FlatStyle = System.Windows.Forms.FlatStyle.System
Me.btnLoadAttachment.Location = New System.Drawing.Point(517, 284)
Me.btnLoadAttachment.Name = "btnLoadAttachment"
Me.btnLoadAttachment.Size = New System.Drawing.Size(174, 23)
Me.btnLoadAttachment.TabIndex = 2
Me.btnLoadAttachment.Text = "Load Attachments"
Me.btnLoadAttachment.UseVisualStyleBackColor = True
'
'lblMsg
'
Me.lblMsg.AutoSize = True
Me.lblMsg.Location = New System.Drawing.Point(36, 361)
Me.lblMsg.Name = "lblMsg"
Me.lblMsg.Size = New System.Drawing.Size(38, 13)
Me.lblMsg.TabIndex = 3
Me.lblMsg.Text = "Ready"
'
'label1
'
Me.label1.AutoSize = True
Me.label1.Location = New System.Drawing.Point(24, 54)
Me.label1.Name = "label1"
Me.label1.Size = New System.Drawing.Size(82, 13)
Me.label1.TabIndex = 4
Me.label1.Text = "Today's Messages"
'
'lblAttach
'
Me.lblAttach.AutoSize = True
Me.lblAttach.Location = New System.Drawing.Point(514, 361)
Me.lblAttach.Name = "lblAttach"
Me.lblAttach.Size = New System.Drawing.Size(148, 13)
Me.lblAttach.TabIndex = 5
Me.lblAttach.Text = "No attachmment downloaded"
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(812, 591)
Me.Controls.Add(Me.lblAttach)
Me.Controls.Add(Me.label1)
Me.Controls.Add(Me.lblMsg)
Me.Controls.Add(Me.btnLoadAttachment)
Me.Controls.Add(Me.lstMsg)
Me.Controls.Add(Me.btnRead)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents btnRead As System.Windows.Forms.Button
Friend WithEvents lstMsg As System.Windows.Forms.ListView
Friend WithEvents btnLoadAttachment As System.Windows.Forms.Button
Friend WithEvents lblMsg As System.Windows.Forms.Label
Friend WithEvents label1 As System.Windows.Forms.Label
Friend WithEvents lblAttach As System.Windows.Forms.Label
End Class
End Namespace
For the issue described in the beginning, the present code provides a solution. Thus I would like to mark this is an answer and close this thread (I know, usually one should not mark their very own answer as answer). Hope this approach is ok.

How to center a PictureBox inside a ScrollableControl and then autoscroll on resize

Having a bit of trouble trying to center the view on the center of the element inside a ScrollableControl.
I have no problems centering the control inside the ScrollableControl, however whenever I try to set AutoScrollPosition, the element inside the scroll container docks to the bottom right corner of the innermost container of the ScrollableControl.
Here is the code that I am using (and I am pretty sure the math is correct) :
MyBase.AutoScrollPosition = New System.Drawing.Point(Canvas1.Left - ((MyBase.Width - Canvas1.Size.Width) / 2), Canvas1.Top - ((MyBase.Height - Canvas1.Size.Height) / 2))
The type of project is actually a UserControl, not a Class, so this is not an "inherited" ScrollableControl per se. It is a UserControl type.
What I find most bizzare, is there doesn't appear to be a ScrollToX, only ScrollControlIntoView, and such, which do not do what I wish.
Basically, the end result, is the center of the Viewable area must be the center of the Control contained inside the Scrollable virtual area. I have the Control centered as such, so this is really just a matter of scrolling it into view so the X,Y of the dead center of the inner control, is in the dead center of the viewable area.
Current code for the entire class
Board.vb
Imports System.ComponentModel
Public Class Board
Private _init As Boolean = False
Private _keys As KeyEventArgs = Nothing
''' <summary>
''' </summary>
''' <filterpriority>3</filterpriority>
''' <remarks></remarks>
<Browsable(False), EditorBrowsable(False)> _
Shadows Property BackgroundImage As Image
Get
Return MyBase.BackgroundImage
End Get
Set(value As Image)
MyBase.BackgroundImage = value
End Set
End Property
<Browsable(False), EditorBrowsable(False)> _
Shadows Property AutoScroll As Boolean
Get
Return MyBase.AutoScroll
End Get
Set(value As Boolean)
MyBase.AutoScroll = value
End Set
End Property
<Browsable(False), EditorBrowsable(False)> _
Shadows Property AutoScrollMinSize As System.Drawing.Size
Get
Return MyBase.AutoScrollMinSize
End Get
Set(value As System.Drawing.Size)
MyBase.AutoScrollMinSize = value
End Set
End Property
Public Property Checkerboard As Boolean
Get
Return Canvas1.CheckeredBackground
End Get
Set(value As Boolean)
Canvas1.CheckeredBackground = value
End Set
End Property
Shadows Property BorderStyle As Windows.Forms.BorderStyle
Get
Return Canvas1.BorderStyle
End Get
Set(value As Windows.Forms.BorderStyle)
Canvas1.BorderStyle = value
End Set
End Property
Private Sub Canvas1_MouseEnter(sender As Object, e As EventArgs) Handles Canvas1.MouseEnter
Me.Focus()
End Sub
Public Sub Add(ByVal Image As System.Drawing.Image)
Dim l As New Layer("Layer " & Canvas1.Layers.Count + 1)
l.Graphics.Add(New Graphic(Image, New Point(10, 10)))
Canvas1.Layers.Add(l)
End Sub
Public Property CanvasSize() As System.Drawing.Size
Get
Return Canvas1.Size
End Get
Set(value As System.Drawing.Size)
Canvas1.Size = value
Me.CenterCanvas()
End Set
End Property
Public Property BoardSize() As System.Drawing.Size
Get
Return Me.AutoScrollMinSize
End Get
Set(value As System.Drawing.Size)
Me.AutoScrollMinSize = value
Me.CenterCanvas()
End Set
End Property
Public Function Remove(ByVal Index As Integer) As Boolean
Try
Canvas1.Layers.RemoveAt(Index)
Return True
Catch ex As Exception
Return False
End Try
End Function
Public Sub RefreshCanvas()
Canvas1.Invalidate()
End Sub
Public Sub CenterCanvas()
Canvas1.Location = New System.Drawing.Point((MyBase.DisplayRectangle.Width - Canvas1.Size.Width) / 2, (MyBase.DisplayRectangle.Height - Canvas1.Size.Height) / 2)
'Debug.Print(Canvas1.Top & ", " & Canvas1.Left)
' Dim y As Integer = (Me.Height - Canvas1.Height) / 2
' Dim x As Integer = (Me.Width - Canvas1.Width) / 2
' x = Canvas1.Left - x
' y = Canvas1.Top - y
' Me.AutoScrollPosition = New System.Drawing.Point(x, y)
End Sub
Public Sub New()
' This call is required by the designer.
InitializeComponent()
_init = True
' Add any initialization after the InitializeComponent() call.
Me.CenterCanvas()
End Sub
Private Sub Board_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
_keys = e
End Sub
Private Sub Board_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
_keys = Nothing
End Sub
Private Sub Board_MouseWheel(sender As Object, e As MouseEventArgs) Handles Me.MouseWheel
Dim l As Layer
l = Canvas1.SelectedLayer
If IsNothing(l) = False Then
Debug.Print("Wheels")
End If
Dim MW As HandledMouseEventArgs = e
MW.Handled = False
End Sub
Private Sub Board_Resize(sender As Object, e As EventArgs) Handles Me.Resize
' If _init Then
' Dim x As Integer = Canvas1.Left - ((MyBase.Width - Canvas1.Size.Width) / 2)
'Dim y As Integer = Canvas1.Top - ((MyBase.Height - Canvas1.Size.Height) / 2)
' MyBase.AutoScrollPosition = New System.Drawing.Point(Canvas1.Left - ((MyBase.Width - Canvas1.Size.Width) / 2), Canvas1.Top - ((MyBase.Height - Canvas1.Size.Height) / 2))
'End If
MyBase.AutoScrollPosition = New System.Drawing.Point( _
Canvas1.Left - MyBase.AutoScrollPosition.X - ((MyBase.ClientSize.Width - Canvas1.Size.Width) \ 2), _
Canvas1.Top - MyBase.AutoScrollPosition.Y - ((MyBase.ClientSize.Height - Canvas1.Size.Height) \ 2))
End Sub
Private Sub Board_SizeChanged(sender As Object, e As EventArgs) Handles Me.SizeChanged
End Sub
End Class
Board.Designer.vb
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Board
Inherits System.Windows.Forms.UserControl
'UserControl1 overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.Canvas1 = New Artisto.Canvas()
CType(Me.Canvas1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'Canvas1
'
Me.Canvas1.Anchor = System.Windows.Forms.AnchorStyles.None
Me.Canvas1.CheckeredBackground = True
Me.Canvas1.Location = New System.Drawing.Point(0, 0)
Me.Canvas1.Name = "Canvas1"
Me.Canvas1.SelectedLayer = Nothing
Me.Canvas1.Size = New System.Drawing.Size(619, 317)
Me.Canvas1.TabIndex = 0
Me.Canvas1.TabStop = False
'
'Board
'
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit
Me.AutoScroll = True
Me.AutoScrollMinSize = New System.Drawing.Size(4096, 2160)
Me.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.Controls.Add(Me.Canvas1)
Me.DoubleBuffered = True
Me.Name = "Board"
Me.Size = New System.Drawing.Size(1266, 523)
CType(Me.Canvas1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Friend WithEvents Canvas1 As Artisto.Canvas
End Class

Serialization with collection property

Ok, so ive written a control that hosts multiple touch screen buttons. This control does this through the manipulation of a collection property marked with the attribute. Now it serializes these buttons in the InitializeComponent() sub that the designer creates for forms. However, whenever I delete the main control(the one that hosts the buttons), the designer doesnt remove the serialization code for the buttons in InitializeComponent() but even worse than that. If I copy the main control from one form and paste it into another form, the buttons aren't copied.
Here is the Code for the ButtonRow object:
Public Class ButtonRow
Inherits Control
Private WithEvents g_colTouchKeys As New TouchScreenButtonCollection
Private g_iMargin As Integer = 0
Public Sub New()
MyBase.DoubleBuffered = True
End Sub
<DefaultValue(0I)> _
Public Property ButtonMargin() As Integer
Get
Return g_iMargin
End Get
Set(ByVal value As Integer)
g_iMargin = value
End Set
End Property
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _ Editor(GetType(ButtonCollectionEditor), GetType(UITypeEditor))> _
Public ReadOnly Property Keys() As TouchScreenButtonCollection
Get
Return g_colTouchKeys
End Get
End Property
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
If MyBase.DesignMode Then
ArrangeButtons()
RenderButtons(e.Graphics)
Else
SetupButtons()
End If
End Sub
Private Sub ArrangeButtons()
Dim icl As Integer = 0
For Each B As TouchScreenKey In g_colTouchKeys
B.Top = 0
B.Left = icl
icl += g_iMargin + B.Width
Next
End Sub
Private Sub AddButtonToControlSurface()
For Each B As TouchScreenKey In g_colTouchKeys
If HasControl(B) = False Then MyBase.Controls.Add(B)
Next
End Sub
Private Sub RemoveControlsNotInCollection()
For Each C As Control In MyBase.Controls
If TypeOf C Is TouchScreenKey Then
If ButtonInCollection(DirectCast(C, TouchScreenKey)) = False Then
MyBase.Controls.Remove(C)
End If
End If
Next
End Sub
Private Function ButtonInCollection(ByVal B As TouchScreenKey) As Boolean
For Each BT As TouchScreenKey In g_colTouchKeys
If BT Is B Then Return True
Next
Return False
End Function
Private Function HasControl(ByVal C As Control) As Boolean
For Each Ct As Control In MyBase.Controls
If C Is Ct Then Return True
Next
Return False
End Function
Private Function CreateDefaultControl() As TouchScreenKey
Dim t As New TouchScreenKey(0, "Default")
t.Left = 0
t.Top = 0
t.Size = New Size(70, 70)
Return t
End Function
Private Sub RenderButtons(ByVal g As Graphics)
For Each B As TouchScreenKey In g_colTouchKeys
Dim rect As Rectangle = New Rectangle(B.Left, B.Top, B.Width, B.Height)
B.PaintButton(g, rect)
Next
End Sub
Private Sub SetupButtons()
ArrangeButtons()
RemoveControlsNotInCollection()
AddButtonToControlSurface()
End Sub
End Class
This is a sample of the InitilizeComponent() procedure after placing the ButtonRow object and adding 3 buttons to its collection:
Private Sub InitializeComponent()
Me.ButtonRow1 = New TouchPadControls.ButtonRow
Me.TouchScreenKey1 = New TouchPadControls.TouchScreenKey
Me.TouchScreenKey2 = New TouchPadControls.TouchScreenKey
Me.TouchScreenKey3 = New TouchPadControls.TouchScreenKey
Me.SuspendLayout()
'
'ButtonRow1
'
Me.ButtonRow1.Keys.AddRange(New TouchPadControls.TouchScreenKey() {Me.TouchScreenKey1, Me.TouchScreenKey2, Me.TouchScreenKey3})
Me.ButtonRow1.Location = New System.Drawing.Point(12, 12)
Me.ButtonRow1.Name = "ButtonRow1"
Me.ButtonRow1.Size = New System.Drawing.Size(321, 111)
Me.ButtonRow1.TabIndex = 0
Me.ButtonRow1.Text = "ButtonRow1"
'
'TouchScreenKey1
'
Me.TouchScreenKey1.ButtonPressGenerates = ""
Me.TouchScreenKey1.Location = New System.Drawing.Point(0, 0)
Me.TouchScreenKey1.Name = "TouchScreenKey1"
Me.TouchScreenKey1.Size = New System.Drawing.Size(80, 80)
Me.TouchScreenKey1.TabIndex = 0
Me.TouchScreenKey1.Text = "TouchScreenKey1"
'
'TouchScreenKey2
'
Me.TouchScreenKey2.ButtonPressGenerates = ""
Me.TouchScreenKey2.Location = New System.Drawing.Point(80, 0)
Me.TouchScreenKey2.Name = "TouchScreenKey2"
Me.TouchScreenKey2.Size = New System.Drawing.Size(80, 80)
Me.TouchScreenKey2.TabIndex = 0
Me.TouchScreenKey2.Text = "TouchScreenKey2"
'
'TouchScreenKey3
'
Me.TouchScreenKey3.ButtonPressGenerates = ""
Me.TouchScreenKey3.Location = New System.Drawing.Point(160, 0)
Me.TouchScreenKey3.Name = "TouchScreenKey3"
Me.TouchScreenKey3.Size = New System.Drawing.Size(80, 80)
Me.TouchScreenKey3.TabIndex = 0
Me.TouchScreenKey3.Text = "TouchScreenKey3"
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(449, 305)
Me.Controls.Add(Me.ButtonRow1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
End Sub
I found the solution to this problem. All I had to do was dispose of the controls to delete them and use a ControlDesigner component to associate child controls with a main control.