|
|
|
This is an update. This question is no longer an issue. I found information
about implementing the Verbs() function of the ControlDesigner. Sorry
for the inconvenience. Did not know if I should delete this question or not.
Hello,
The code below adds an action to select 1 of 2 panel configurations:
"SelectPanel2Type" or "SelectPanel3Type".
The controls action list displays the current 'PanelType' selection.
When you click on the current item, the current item text changes to the second panel
text:
Example: If "SelectPanel2Type" is displayed, clicking on it changes to "SelectPanel3Type"
and visa versa.
This functions as expected.
The problem:
The action is also displayed and can be selected from the attributes panel of the Properties window, but when I click on the action in the attributes panel, the text in the attributes
panel does not change to the opposite panel and I cannot select the opposite configuration.
Example:
If "Select Panel2Type" is displayed, when I click on it, the action is performed in
the control, but the text in the attributes panel does not change to "Select Panel3Type".
If I deselect the control and reselect it, the attributes panel will be updated
to "Select Panel3Type".
Is there something that I am not doing to update the attributes panel correctly?
Thank you.
Friend Class SPCActionList
Inherits System.ComponentModel.Design.DesignerActionList
' Host object
Private HostControl As SplitPanelCtrl = Nothing
' Cache a reference to the DesignerActionUIService host.
Private _DesignerActionUIService As DesignerActionUIService
Public Sub New(ByVal component As IComponent)
MyBase.New(component)
' Cache a reference to the control.
HostControl = DirectCast(component, SplitPanelCtrl)
' Cache a reference to update action
_DesignerActionUIService = CType(GetService(GetType(DesignerActionUIService)), DesignerActionUIService)
End Sub
Public Overrides Function GetSortedActionItems() As DesignerActionItemCollection
Dim items As New DesignerActionItemCollection()
items.Add(New DesignerActionHeaderItem("Panel Type Selection"))
items.Add(New DesignerActionMethodItem(Me, _
IIf(Me.HostControl.PanelType = enumPanelType.PanelType2, "SelectPanel3Type", "SelectPanel2Type"), _
IIf(Me.HostControl.PanelType = enumPanelType.PanelType2, "Select Panel3Type", "Select Panel2Type"), _
IIf(Me.HostControl.PanelType = enumPanelType.PanelType2, "Select Panel3Type", "Select Panel2Type"), _
IIf(Me.HostControl.PanelType = enumPanelType.PanelType2, "Select Panel3Type", "Select Panel2Type"), _
True))
Return items
End Function
Private Sub SelectPanel2Type()
TypeDescriptor.GetProperties(HostControl)("PanelType").SetValue(MyBase.Component, enumPanelType.PanelType2)
Me._DesignerActionUIService.Refresh(HostControl)
End Sub
Private Sub SelectPanel3Type()
TypeDescriptor.GetProperties(HostControl)("PanelType").SetValue(MyBase.Component, enumPanelType.PanelType3)
Me._DesignerActionUIService.Refresh(HostControl)
End Sub
End Class
-- modified 19-Dec-17 12:14pm.
|
|
|
|
|
I am working on a project where an access database calls a batch file that then calls a .vbs file. Within the .vbs file my code is to open a telnet session, connect to my companies warehouse management system, login, call a specific program, enter some information on the screen which executes the program, then logout.
This is where it gets interesting. If I manually run the batch file which is on my local C:\ drive the batch file calls the .vbs script and the .vbs script executes flawlessly. Keep in mind that the point of this is to automate and not have a person manually run the batch file or do everything that the .vbs script is setup to do. When I use a Microsoft Access macro to open the same exact batch file which then calls the .vbs script I run into problems. The batch file executes as expected, the .vbs script opens the command prompt however I get a message that telnet does not exist. How is this possible? The access database is on my local C:\ drive along with the batch file and .vbs script.
Here is my .vbs code which I know is not the problem since it will work when I run it manually. Does using a program to call telnet interact differently or cause security issues within Microsoft windows?
My .vbs file code (for security purposes I changed/put server, username, password, program name,file name instead of real values):
Dim objShell
Set objShell = CreateObject("WScript.Shell")
objShell.Run "C:\windows\system32\cmd.exe"
Wscript.Sleep 5000
objShell.SendKeys "telnet server"
objShell.SendKeys "{ENTER}"
Wscript.Sleep 3000
objShell.SendKeys "username"
objShell.SendKeys "{ENTER}"
Wscript.Sleep 3000
objShell.SendKeys "password"
objShell.SendKeys "{ENTER}"
Wscript.Sleep 300
objShell.SendKeys "{ENTER}"
Wscript.Sleep 3000
objShell.SendKeys "1"
objShell.SendKeys "{ENTER}"
Wscript.Sleep 3000
objShell.SendKeys "call programname "
objShell.SendKeys "{ENTER}"
Wscript.Sleep 3000
objShell.SendKeys "filename"
objShell.SendKeys "{ENTER}"
Wscript.Sleep 3000
objShell.SendKeys "{F6}"
Wscript.Sleep 3000
objShell.SendKeys "{F3}"
Wscript.Sleep 3000
objShell.SendKeys "exit"
objShell.SendKeys "{ENTER}"
Wscript.Sleep 3000
bjShell.SendKeys "exit"
objShell.SendKeys "{ENTER}"
Set objShell = Nothing
My batch file simply calls the .vbs file
|
|
|
|
|
It is probably due to environment variables not being setup in the call to cmd. Try adding the full directory path to telnet.exe.
modified 18-Dec-17 16:40pm.
|
|
|
|
|
I tried full path to cmd.exe
C:\windows\system32\cmd.exe and get same result.
Why would the script work when running it manually via a double click of the .vbs file however when using a program such as outlook or access to run the same exact .vbs file results in an error "telnet not recognized".....error
|
|
|
|
|
Why did you think that would change anything? Please read my previous suggestion again.
|
|
|
|
|
I did. You said use thebfull path for cmd.exe which is c:\windows\system32\cmd.exe
I guess I dont understand the direction you are giving.
The bigger issue is what I outlined about executing manually vs with another program. Is cmd.exe and telnet limited in how its used for security reasons?
Thanks
|
|
|
|
|
No, he was referring to the full path for Telnet, which is "C:\Windows\System32\Telnet.exe".
Also, using SendKeys is not recommended. What if the user clicks another window or the system pops up a dialog from something else in the middle of all those key strokes you're sending? Bad things will happen.
The better way to do it would be to redirect the Input stream of the CMD Process you launched and write your data to the stream instead.
System.ItDidntWorkException: Something didn't work as expected.
C# - How to debug code[ ^].
Seriously, go read these articles.
Dave Kreskowiak
|
|
|
|
|
Duh....lol....i tried the full path for telnet.exe and run into a similar problem as cmd.exe. i input the commands and server and it now it doesnt connect when using a program to execute the .vbs however if i manually execute my .vbs it works.
Im not concerned with the sendkeys because this script will be running at a time when no one will be accessing the pc.
Sounds more and more like a security issue.
|
|
|
|
|
If it's telling you telnet.exe is a "Bad command or filename", it's because it can't find the executable on whatever the PATH environment is set to. This may be different from what you see when you type SET PATH at a CMD prompt yourself. That's why you have to specify the entire path to telnet.exe in the .VBS file.
System.ItDidntWorkException: Something didn't work as expected.
C# - How to debug code[ ^].
Seriously, go read these articles.
Dave Kreskowiak
|
|
|
|
|
Sendkeys is limited, because it is a liability in scripts.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Please I need help with this
So i have a dictionary of words and their corresponding Part Of Speech in my data base...
I want a user to enter a text in a text box then after clicking a button..
My code should determine if the text is valid or not using my dictionary of words
|
|
|
|
|
Onuche Abraham DaCatalyst wrote: My code should determine if the text is valid or not using my dictionary of words So what are the rules that your code needs to implement?
|
|
|
|
|
I have created a control similar to the SplitContainer with a host control
and 2 custom panels. All controls inherit ParentControlDesigner. I have a
custom splitter control to separate the panels.
Problem: When I resize the panels using the splitter control, the 'designer border'
that surrounds the selected panel does not resize for the selected control.
This border is drawn by the designer; not my code. Is there a way to refresh
the designer so it will redraw the border of the selected control?
Thank you
|
|
|
|
|
You don't. There's no way to tell the designer to refresh itself from your own control, nor should that even work. The control should only be concerned about itself.
Your control has to be properly written to expose its properties and events correctly so the designer can use them without you trying to tell it to do so.
System.ItDidntWorkException: Something didn't work as expected.
C# - How to debug code[ ^].
Seriously, go read these articles.
Dave Kreskowiak
|
|
|
|
|
If the code I gave to you not helped you to solve that problem you should show us your actual ParentControlDesigner and the part of your control which is responsible for the painting to help you with the modification.
|
|
|
|
|
Hello Ralf,
I was hoping there would be a function call that would cause the designer
to re-select the selected child panel which would then redraw the designer's border.
According to another post, there is not.
Since I am new to control design and this control is for my personal use, I can live
with this imperfection in my code for now.
I do not know how to mark this question as no longer relevant but if there is
a box or something I am suppose to select, please let me know.
Thank you for your response.
|
|
|
|
|
I'm not sure if I understood you in the right way ... but independent from that : have you see that I posted a code-replay too in this question ?
Also :
I'm very sure that all what you want to have is to (nearly) realizable like you want to have.
Also I'm very familiar with Control-Design and most of the environment around - so I'm sure that I could help you. Give it a try and help me to help you ...
|
|
|
|
|
Hello Ralf,
I'm sorry. I think I have confused you with my question and responses. I will
describe my issue again and try to be more clear.
My control functions like the 'SplitContainer' in the toolbox.
Normal operation in run mode.
It has a custom 'Host' UserControl that implements a ParentControlDesigner and it has
2 child UserControls, Panel1 and Panel2 which also implement a ControlDesigner. I also
have a custom control that does nothing but separate the 2 panels, I call it
the 'Splitter'. The splitter control is a simple UserControl. The splitter overrides MouseDown, MouseMove, and MouseUp, to move itself within the host control and when MouseUp occurs, the splitter raises an event to the host and the host resizes the 2 panels based on the splitters' position. This works fine normal operation.
Functionality in design mode.
Since events do not function in design mode, I have created a Behaviour for the host
control that handles OnMouseDown, OnMouseMove, and OnMouseUp to perform the same action
as described above to move the splitter bar and when the OnMouseUp occurs, I have a Shadowed property called SplitterOffset that informs the host of the splitter's change in position
and the host resizes the panels correctly.
All of this works fine.
If you look at the SplitContainer from the toolbox, when you select a panel, the selected panel displays 3 borders.
1. The inner most border is for 'Padding'; drawn by the panel.
2. The center border is for 'Margin'; drawn by the panel.
3. The outermost border; This border is drawn by the IDE designer to indicate the
selected panel.
My control draws borders 1 and 2 as expected and the IDE draws border 3, outermost border
as expected.
Here is the issue in design mode:
After moving the Splitter, my Host control resizes the panels as expected and the
Margin and Padding borders are drawn correctly for each panel. But, the IDE designer
is not aware of my host control resizing the panels and therefore the outer border
mentioned above (3.) is not redrawn to match the new size of the selected panel.
This does not affect the normal operation of the control at runtime. This is
merely a visual issue in design mode. I hope I am not more confusing. If this makes
since to you and you have a suggestion, I would appreciate it. If this is just
confusing, I apologize as I am just learning concerning the designer. As I learn
more I will revisit this issue and perhaps figure it out later.
addendum,
After writing the above I have thought about this a little more and I think
my problem probably is the result of how I have implemented Panel1 and Panel2.
In the same way that the SplitContainer has hidden certain properties from the user,
I have also hid the same properties to prevent the user from changing them in the mycontrol.designer.vb file. Possibly because the properties are hidden, the designer
cannot update properly. I will have to experiment with this. I'm sure you could look at
my code and figure it out but I don't want to take up all of your time with such
a small issue.
Thanks again for helping me.
Best regards
-- modified 15-Dec-17 17:04pm.
|
|
|
|
|
Hello,
I think I understand your requirement ... and ... my code-snippet was much nearer to your requirement as I (or you) thought.
So ... let's start once again :
When I began with Controls-Development I startet like you - each and every customized Control was a UserControl. That is good for start but often not good for Behaviour.
So nowadays most of my controls derive from Control and normaly I try not to use other controls inside my Control.
The next part you should know is (that is also a part of your explaining) :
Nearly every action of a control which is possible during RunTime is also possible during DesignTime (this part can be realized with the ControlDesigner) - but it's not easy to find out how to realize that. So ... what I suggest to do for you is : I work-over my "Split-Control" to be a Stand-alone Control and post you the Code. But this will take a little time. After this you take a look at it, try to understand it and don't be angry with some german-named Variables. After this we can discuss it and/or I answer further questions.
Best regards to you
Ralf
|
|
|
|
|
 ... and here the code from my Control (it isn't complete anymore but it could show you how Splitting could be done) :
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Runtime.CompilerServices
Imports System.Windows.Forms.Design
Imports System.Windows.Forms.Design.Behavior
Imports System.Drawing.Drawing2D
<Description("Anzeige zur Darstellung eines Analogwertes mit zugehörigem Beschreibungs-Text und Einheit")>
<ToolboxItem(True)>
<Designer(GetType(RMValueDisplay.Designer))>
Public Class RMValueDisplay
Inherits Control
Implements ICustomTypeDescriptor
#Region "Konstruktor / Dispose"
Public Sub New()
Me.Size = New Size(300, 40)
Me.Invalidate()
End Sub
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
MyBase.Dispose(disposing)
End Sub
#End Region
#Region "Echte Transparenz herstellen"
Private Sub SetTransparenz()
Me.SetStyle(ControlStyles.Opaque, True)
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, False)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
End Sub
Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H20
Return cp
End Get
End Property
#End Region
#Region "ausgeblendete Properties"
Private myRemoveProperties As String() = {
"AllowDrop",
"Anchor",
"BackgroundImage",
"BackgroundImageLayout",
"CausesValidation",
"Cursor",
"Dock",
"Enabled",
"ImeMode",
"Margin",
"MaximumSize",
"MinimumSize",
"Padding",
"RightToLeft",
"TabIndex",
"TabStop",
"Text",
"UseWaitCursor"
}
#End Region
#Region "eigene Definitionen"
<TypeConverter(GetType(SpaltenTrennerDefinition.Converter))>
Public Class SpaltenTrennerDefinition
<Description("Position der 1. Spalte im Control")>
Property Pos1 As Int32
Get
Return my_Pos1
End Get
Set(ByVal value As Int32)
If my_Pos1 <> value Then
If value < 0 Then value = 0
If value > my_Pos2 Then value = my_Pos2
my_Pos1 = value
If Parent IsNot Nothing Then my_Pos1Proz = CSng(my_Pos1) / CSng(CType(Parent, Control).Width)
RaiseEvent Changed()
End If
End Set
End Property
Private my_Pos1Proz As Single = 0.6
Private my_Pos1 As Int32 = my_Pos1Proz * 300
<Description("Position der 2. Spalte im Control")>
Property Pos2 As Int32
Get
Return my_Pos2
End Get
Set(ByVal value As Int32)
If my_Pos2 <> value Then
my_Pos2 = value
If my_Pos2 < my_Pos1 Then my_Pos2 = my_Pos1
If Parent IsNot Nothing Then my_Pos2Proz = CSng(my_Pos2) / CSng(CType(Parent, Control).Width)
RaiseEvent Changed()
End If
End Set
End Property
Private my_Pos2Proz As Single = 0.85
Private my_Pos2 As Int32 = my_Pos2Proz * 300
Public Event Changed()
Property Parent As Object = Nothing
Public Sub New(xParent As Object, setPos1 As Int32, setPos2 As Int32)
Parent = CType(xParent, Control)
Dim my_Width As Integer = Parent.Width
If setPos1 < 0 Then setPos1 = 0
If setPos2 < 0 Then setPos2 = 0
If setPos1 > setPos2 Then setPos1 = setPos2
If setPos2 < setPos1 Then setPos2 = setPos1
If setPos1 > my_Width Then setPos1 = my_Width
If setPos2 > my_Width Then setPos2 = my_Width
my_Pos1 = setPos1
my_Pos1Proz = my_Pos1 / my_Width
my_Pos2 = setPos2
my_Pos2Proz = my_Pos2 / my_Width
RaiseEvent Changed()
End Sub
Public Sub New()
End Sub
Public Sub New(setPos1 As Int32, setPos2 As Int32)
If setPos1 < 0 Then setPos1 = 0
If setPos2 < 0 Then setPos2 = 0
If setPos1 > setPos2 Then setPos1 = setPos2
If setPos2 < setPos1 Then setPos2 = setPos1
my_Pos1 = setPos1
my_Pos2 = setPos2
RaiseEvent Changed()
End Sub
Public Sub ReCalculate(my_Width As Integer)
my_Pos1 = my_Pos1Proz * my_Width
my_Pos2 = my_Pos2Proz * my_Width
End Sub
Public Overrides Function ToString() As String
Return my_Pos1.ToString + "; " + my_Pos2.ToString
End Function
Public Class Converter
Inherits ExpandableObjectConverter
Public Overloads Overrides Function CanConvertFrom(ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean
If sourceType Is GetType(String) Then Return True
Return MyBase.CanConvertFrom(context, sourceType)
End Function
Public Overloads Overrides Function ConvertFrom(ByVal context As ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object
If value.GetType Is GetType(String) Then
Dim s As String = CType(value, String)
Dim sa As String() = Split(s, ";")
If sa.Length >= 2 Then
Dim p1, p2 As Integer
If Integer.TryParse(sa(0), p1) AndAlso Integer.TryParse(sa(1), p2) Then
Return New SpaltenTrennerDefinition(context.Instance, p1, p2)
End If
End If
Throw New FormatException()
End If
Return MyBase.ConvertFrom(context, culture, value)
End Function
Public Overloads Overrides Function CanConvertTo(context As System.ComponentModel.ITypeDescriptorContext, destinationType As System.Type) As Boolean
If destinationType Is GetType(System.ComponentModel.Design.Serialization.InstanceDescriptor) Then Return True
Return MyBase.CanConvertTo(context, destinationType)
End Function
Public Overloads Overrides Function ConvertTo(context As System.ComponentModel.ITypeDescriptorContext, culture As System.Globalization.CultureInfo, value As Object, destinationType As System.Type) As Object
If destinationType Is GetType(System.ComponentModel.Design.Serialization.InstanceDescriptor) Then
Dim ctor As Reflection.ConstructorInfo
Dim s As String = value.ToString
Dim sa As String() = Split(s, ";")
If sa.Length >= 2 Then
Dim p1, p2 As Integer
If Integer.TryParse(sa(0), p1) AndAlso Integer.TryParse(sa(1), p2) Then
ctor = GetType(SpaltenTrennerDefinition).GetConstructor(New Type() {GetType(Int32), GetType(Int32)})
Return New System.ComponentModel.Design.Serialization.InstanceDescriptor(ctor, New Object() {p1, p2}, True)
End If
End If
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function
End Class
End Class
#End Region
#Region "Expandable Properties"
<Category("Layout"), Description("Definition der Spalten-Aufteilung im Control")>
<RefreshProperties(RefreshProperties.All)>
Property SpaltenTrenner As SpaltenTrennerDefinition
Get
Return my_SpaltenTrenner
End Get
Set(ByVal value As SpaltenTrennerDefinition)
my_SpaltenTrenner = value
Me.Invalidate()
End Set
End Property
Private WithEvents my_SpaltenTrenner As New SpaltenTrennerDefinition()
#End Region
#Region "Properties zur Darstellung"
<Category("Layout"), Description("Definition der Größe des Control")>
<RefreshProperties(RefreshProperties.All)>
Shadows Property Size As Size
Get
Return MyBase.Size
End Get
Set(ByVal value As Size)
If value.Width <> MyBase.Width Then
MyBase.Width = value.Width
my_SpaltenTrenner.ReCalculate(value.Width)
End If
MyBase.Height = value.Height
End Set
End Property
<Category("Darstellung"), Description("legt die Hintergrundfarbe im Control fest")>
<DefaultValue(GetType(Color), "LightGray")>
Shadows Property BackColor As Color
Get
Return my_BackColor
End Get
Set(ByVal value As Color)
MyBase.BackColor = value
my_BackColor = value
Me.Invalidate()
End Set
End Property
Private my_BackColor As Color = Color.LightGray
<Category("Darstellung"), Description("legt die Schriftfarbe im Control fest")>
<DefaultValue(GetType(Color), "Black")>
Shadows Property ForeColor As Color
Get
Return my_ForeColor
End Get
Set(ByVal value As Color)
MyBase.ForeColor = value
my_ForeColor = value
Me.Invalidate()
End Set
End Property
Private my_ForeColor As Color = Color.Black
<Category("Darstellung"), Description("legt die Rahmen-Farbe des Labels fest")>
<DefaultValue(GetType(System.Drawing.Color), "Gray")>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
Property BorderColor As Color
Get
Return my_BorderColor
End Get
Set(ByVal value As Color)
my_BorderColor = value
Me.Invalidate()
End Set
End Property
Private my_BorderColor As Color = Color.Gray
<Category("Anzeige"), Description("legt die Schriftart im Control fest")>
Shadows Property Font As Font
Get
Return MyBase.Font
End Get
Set(ByVal value As Font)
MyBase.Font = value
End Set
End Property
#End Region
#Region "interne Aktionen"
Private Sub SpaltenTrenner_Changed() Handles my_SpaltenTrenner.Changed
Me.Invalidate()
End Sub
Protected Overrides Sub OnResize(e As EventArgs)
my_SpaltenTrenner.ReCalculate(Me.Width)
MyBase.OnResize(e)
Me.Invalidate()
End Sub
Protected Overrides Sub OnHandleCreated(e As System.EventArgs)
myParent = Parent
isInitialized = True
Me.Invalidate()
MyBase.OnHandleCreated(e)
End Sub
Private WithEvents myParent As Control
Private isInitialized As Boolean = False
#End Region
#Region "Implementierung der ISelectionService-Schnittstelle um festzustellen, dass das Control angewählt wurde"
<Browsable(False)>
ReadOnly Property Activated As Boolean
Get
If selectionService IsNot Nothing Then Return selectionService.GetComponentSelected(Me)
Return False
End Get
End Property
Private selectionService As ISelectionService
<Browsable(False), EditorBrowsable(EditorBrowsableState.Never)>
Public Overrides Property Site() As ISite
Get
Return MyBase.Site
End Get
Set(ByVal Value As ISite)
MyBase.Site = Value
If MyBase.Site Is Nothing Then Return
selectionService = Me.Site.GetService(GetType(ISelectionService))
End Set
End Property
#End Region
#Region "Properties bedingt ein-/ausblenden"
Private Function FilterProperties(ByVal origProperties As PropertyDescriptorCollection) As PropertyDescriptorCollection
Dim myPD As PropertyDescriptor
Dim myListe As New List(Of PropertyDescriptor)
Dim setHidden As Boolean
For i As Integer = 0 To origProperties.Count - 1
myPD = origProperties.Item(i)
setHidden = False
If setHidden Then
myPD = TypeDescriptor.CreateProperty(myPD.ComponentType, myPD, New Attribute() {New BrowsableAttribute(False), New EditorBrowsableAttribute(EditorBrowsableState.Never)})
End If
If Not myRemoveProperties.Contains(myPD.Name) Then myListe.Add(myPD)
Next
Dim myPDListe(myListe.Count - 1) As PropertyDescriptor
myListe.CopyTo(myPDListe)
Return New PropertyDescriptorCollection(myPDListe)
End Function
#End Region
#Region "ICustomTypeDescriptor - Properties ein-/ausblenden"
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetAttributes() As System.ComponentModel.AttributeCollection Implements System.ComponentModel.ICustomTypeDescriptor.GetAttributes
Return TypeDescriptor.GetAttributes(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetClassName() As String Implements System.ComponentModel.ICustomTypeDescriptor.GetClassName
Return TypeDescriptor.GetClassName(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetComponentNaMe() As String Implements System.ComponentModel.ICustomTypeDescriptor.GetComponentName
Return TypeDescriptor.GetComponentName(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetConverter() As System.ComponentModel.TypeConverter _
Implements System.ComponentModel.ICustomTypeDescriptor.GetConverter
Return TypeDescriptor.GetConverter(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetDefaultEvent() As System.ComponentModel.EventDescriptor _
Implements System.ComponentModel.ICustomTypeDescriptor.GetDefaultEvent
Return TypeDescriptor.GetDefaultEvent(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetDefaultProperty() As System.ComponentModel.PropertyDescriptor _
Implements System.ComponentModel.ICustomTypeDescriptor.GetDefaultProperty
Return TypeDescriptor.GetDefaultProperty(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetEditor(ByVal editorBaseType As System.Type) As Object _
Implements System.ComponentModel.ICustomTypeDescriptor.GetEditor
Return TypeDescriptor.GetEditor(Me, editorBaseType, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Overloads Function GetEvents() As System.ComponentModel.EventDescriptorCollection _
Implements System.ComponentModel.ICustomTypeDescriptor.GetEvents
Return TypeDescriptor.GetEvents(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Overloads Function GetEvents(ByVal attributes() As System.Attribute) As System.ComponentModel.EventDescriptorCollection _
Implements System.ComponentModel.ICustomTypeDescriptor.GetEvents
Return TypeDescriptor.GetEvents(Me, attributes, True)
End Function
<Description("Returns the wrapped object.")> _
Public Function GetPropertyOwner(ByVal pd As System.ComponentModel.PropertyDescriptor) As Object _
Implements System.ComponentModel.ICustomTypeDescriptor.GetPropertyOwner
Return Me
End Function
<Description("Returns the list of properties as defined in the constructor")> _
Public Overloads Function GetProperties() As System.ComponentModel.PropertyDescriptorCollection _
Implements System.ComponentModel.ICustomTypeDescriptor.GetProperties
Dim pd As PropertyDescriptorCollection = TypeDescriptor.GetProperties(Me, True)
Return FilterProperties(pd)
End Function
<Description("Returns the list of properties as defined in the constructor")> _
Public Overloads Function GetProperties(ByVal attributes() As System.Attribute) As System.ComponentModel.PropertyDescriptorCollection _
Implements System.ComponentModel.ICustomTypeDescriptor.GetProperties
Dim pd As PropertyDescriptorCollection = TypeDescriptor.GetProperties(Me, attributes, True)
Return FilterProperties(pd)
End Function
#End Region
#Region "Designer"
Public Class Designer
Inherits System.Windows.Forms.Design.ControlDesigner
Private HostControl As RMValueDisplay = Nothing
Public Overrides Sub Initialize(ByVal component As System.ComponentModel.IComponent)
MyBase.Initialize(component)
HostControl = DirectCast(component, RMValueDisplay)
End Sub
Protected Overrides Sub PreFilterProperties(ByVal properties As System.Collections.IDictionary)
MyBase.PreFilterProperties(properties)
properties.Remove("AccessibleDescription")
properties.Remove("AccessibleName")
properties.Remove("AccessibleRole")
properties.Remove("ApplicationSettings")
properties.Remove("DataBindings")
properties.Remove("ContextMenuStrip")
properties.Remove("GenerateMember")
properties.Remove("Locked")
End Sub
Public Overrides ReadOnly Property SnapLines As System.Collections.IList
Get
Dim snaps As ArrayList = New ArrayList(MyBase.SnapLines)
snaps.Add(New SnapLine(SnapLineType.Horizontal, Me.Control.Height \ 2))
snaps.Add(New SnapLine(SnapLineType.Vertical, Me.Control.Width \ 2))
Return snaps
End Get
End Property
Protected Overrides Sub OnSetCursor()
Dim myPoint As Point = HostControl.PointToClient(Cursor.Position)
If inShiftPosition(myPoint) > 0 Then
If Dragging_Aktiv Then
Cursor.Current = Cursors.Arrow
Else
Cursor.Current = Cursors.SizeWE
End If
Else
MyBase.OnSetCursor()
End If
End Sub
Private Function inShiftPosition(ByVal p As Point) As Integer
If HostControl IsNot Nothing AndAlso HostControl.Activated Then
If (p.X >= HostControl.SpaltenTrenner.Pos1 - Dragging_ShiftHysterese) AndAlso (p.X <= HostControl.SpaltenTrenner.Pos1 + Dragging_ShiftHysterese) Then
Return 1
ElseIf (p.X >= HostControl.SpaltenTrenner.Pos2 - Dragging_ShiftHysterese) AndAlso (p.X <= HostControl.SpaltenTrenner.Pos2 + Dragging_ShiftHysterese) Then
Return 2
Else
Return 0
End If
Else
Return 0
End If
End Function
Private Dragging_ShiftHysterese As Integer = 3
Private Dragging_Aktiv As Boolean = False
Private Dragging_ShiftPoint As Integer = 0
Private Dragging_Offset As Integer = 0
Protected Overrides Sub OnMouseDragBegin(ByVal x As Integer, ByVal y As Integer)
If HostControl Is Nothing Then Exit Sub
Dim myPoint As Point = HostControl.PointToClient(New Point(x, y))
Dragging_ShiftPoint = inShiftPosition(myPoint)
If Dragging_ShiftPoint = 1 Then
Dragging_Offset = HostControl.SpaltenTrenner.Pos1 - myPoint.X
Dragging_Aktiv = True
ElseIf Dragging_ShiftPoint = 2 Then
Dragging_Offset = HostControl.SpaltenTrenner.Pos2 - myPoint.X
Dragging_Aktiv = True
Else
MyBase.OnMouseDragBegin(x, y)
End If
End Sub
Protected Overrides Sub OnMouseDragMove(ByVal x As Integer, ByVal y As Integer)
If HostControl Is Nothing Then Exit Sub
Dim myPoint As Point = HostControl.PointToClient(New Point(x, y))
If Dragging_Aktiv Then
If Dragging_ShiftPoint = 1 Then
HostControl.SpaltenTrenner.Pos1 = myPoint.X + Dragging_Offset
ElseIf Dragging_ShiftPoint = 2 Then
HostControl.SpaltenTrenner.Pos2 = myPoint.X + Dragging_Offset
End If
Else
MyBase.OnMouseDragMove(x, y)
End If
End Sub
Protected Overrides Sub OnMouseDragEnd(ByVal cancel As Boolean)
Dragging_Aktiv = False
MyBase.OnMouseDragEnd(cancel)
End Sub
Protected Overrides Sub OnPaintAdornments(ByVal pe As System.Windows.Forms.PaintEventArgs)
If HostControl Is Nothing Then Exit Sub
If HostControl.Activated Then
Dim borderPen As New Pen(HostControl.ForeColor)
If HostControl.BackColor = Color.Transparent Then borderPen = New Pen(HostControl.Parent.ForeColor)
borderPen.DashStyle = Drawing2D.DashStyle.Dash
pe.Graphics.DrawRectangle(borderPen, 0, 0, HostControl.SpaltenTrenner.Pos1 - 1, HostControl.Height - 1)
pe.Graphics.DrawRectangle(borderPen, HostControl.SpaltenTrenner.Pos1 + 1, 0, HostControl.SpaltenTrenner.Pos2 - HostControl.SpaltenTrenner.Pos1 - 2, HostControl.Height - 1)
pe.Graphics.DrawRectangle(borderPen, HostControl.SpaltenTrenner.Pos2 + 1, 0, HostControl.Width - HostControl.SpaltenTrenner.Pos2 - 2, HostControl.Height - 1)
borderPen.Dispose()
Else
If (HostControl.BackColor = Color.Transparent) Then
Dim borderPen As New Pen(HostControl.ForeColor)
If HostControl.BackColor = Color.Transparent Then borderPen = New Pen(HostControl.Parent.ForeColor)
borderPen.DashStyle = Drawing2D.DashStyle.Dash
pe.Graphics.DrawRectangle(borderPen, 0, 0, HostControl.Width - 1, HostControl.Height - 1)
borderPen.Dispose()
End If
End If
MyBase.OnPaintAdornments(pe)
End Sub
End Class
#End Region
End Class
|
|
|
|
|
Hello,
Thank you for this sample code. It is very interesting to me. Some of this implementation
is new to me and I will have to study to see how I can apply to my control. It may take
a couple of days for me to understand your sample and apply to my control. I will let you
know when I have figured it out.
Thanks again for your continued efforts.
Best regards
|
|
|
|
|
Hello Ralf,
The sample code that you supplied is excellent.
It is so much simpler than the sample code I started with from the MSDN library.
I have gained more understanding of the ControlDesigner from your sample.
I have recreated my control using your sample as a guide and everything is working
good now. I can select my child panels, resize them, and drag and drop controls within
the panels now.
I really appreciate your patience and desire to help me with this problem.
Many thanks 
|
|
|
|
|
You are welcome ... and I'm very glad about your response.
And you know : if you have further questions ... feel free to ask ...
Additional :
I don't know your goal ... but I suppose that you don't need Panels for the Rest. But that is your turn to decide.
|
|
|
|
|