كاتب الموضوع : silverlight
الأخوة الكرام قد يبدو للوهلة الأولي لك عزيزي القارئ أن الهدف من الكود هو كيفية بناء الألة الحاسبة وفي واقع الأمر ليس هذا هو الهدف من الكود علي الاطلاق لأن الجميع يعلم جيدا كيفية بناء الة حاسبة علمية ولكي اوضح الأمر سأعود بكم الي موضوع كنت قد كتبته عن كيفية تغيير شكل الفورم باستخدام +GDI
وتحديدا في المشاركة رقم 30 في الرابط أعلاه قام أحد الزملاء وهو الأخ الفاضل mmmdev بكتابة استفسار عن كيفية بناء كونترول للألة الحاسبة وكان استفساره كالتالي
هل من الممكن بناء كونترول عبارة عن زر أو باتون وبجانبه مربع نص بحيث عندما يتم الضغط علي الزر يظهر كونترول الألة الحاسبة المنسدلة وعندما نضغط علي الباتون مرة ثانية تختفي الألة الحاسبة المنسدلة
في واقع الأمر لقد كتبت الكود الخاص بهذا الكونترول ليس فقط لكي يتم استخدامة مع الألة الحاسبة بل يمكن استخدامة مع اي كونترول اخر تصممه بنفسك
ولقد كتبت مثالين لتوضيح الأمر المثال الأول عبارة عن ألة حاسبة منسدلة والثاني عبارة عن ساعة عقارب منسدلة
وفكرة الكونترول تعتمد علي استخدام ToolStripControlHost ومن ثم يتم إضافة كونترول الألة الحاسبة أو اي كونترول اخر اليه
والكود الخاص بالكونترول سيكون كالتالي
كود :
Imports System.ComponentModel
Public Class DropDownCalculator
Inherits Control
#Region "Variables"
Private m_TextRect As New Rectangle()
Private m_ButtonRect As New Rectangle()
Private m_Left As Short
Private m_Top As Short
Private m_TsDropDown As New ToolStripDropDown
Private m_TsHost As ToolStripControlHost
Private m_Control As Control = Nothing
Private IsResize As Boolean = False
Private IsOpen As Boolean
Public Event OnDropDown(ByVal sender As Object, ByVal IsDropdown As Boolean)
Private m_PanelSize As Size = New Size(150, 150)
Private Const PushButtonWidth As Integer = 15
Private Shared BorderSize As Integer = SystemInformation.Border3DSize.Width * 2
Private m_Colorlight As Color = Color.Cyan
Private m_ColorDark As Color = Color.FromArgb(150, 0, 0, 0)
Private IsMouseDownButton As Boolean = False
Private m_Text As String = "Calculator"
#End Region
#Region "Constructor"
Public Sub New()
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
Me.SetStyle(ControlStyles.UserPaint, True)
Me.SetStyle(ControlStyles.StandardClick, True)
Me.SetStyle(ControlStyles.Selectable, True)
Me.SetStyle(ControlStyles.DoubleBuffer, True)
Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True)
AddHandler m_TsDropDown.Closing, AddressOf tsdd_Close
AddHandler m_TsDropDown.Opening, AddressOf tsdd_Open
IsResize = False
' -----------------------------------
' هنا يتم ربط كونترول الألة الحاسبة
' أو أي كونترول اخر تصممه بنفسك
Dim calc As New CalculatorBase()
m_Control = calc
' -----------------------------------
Me.MinimumSize = New Size(75, 25)
Me.MaximumSize = New Size(75, 25)
End Sub
#End Region
#Region "Property"
<Browsable(True)> _
<Category("Appearance DropDown")> _
<Description("Get or Set the Primary Color of the Text")> _
<DefaultValueAttribute(GetType(Color), "Cyan")> _
Public Property ColorLight() As Color
Get
Return m_Colorlight
End Get
Set(ByVal value As Color)
If (value <> (m_Colorlight)) Then
m_Colorlight = value
Invalidate()
End If
End Set
End Property
<Browsable(False)> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
Public Property PanelSize() As System.Drawing.Size
Get
Return m_PanelSize
End Get
Set(ByVal value As System.Drawing.Size)
If m_Control Is Nothing Then
m_PanelSize = value
Else
m_PanelSize = Size.Add(m_Control.Size, m_TsDropDown.Padding.Size)
End If
Invalidate()
End Set
End Property
#End Region
#Region "Method"
Private Sub DrawArrow(ByVal g As Graphics, ByVal dropDownRect As Rectangle)
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
Dim middle As New Point(Convert.ToInt32(dropDownRect.Left + dropDownRect.Width / 2), _
Convert.ToInt32(dropDownRect.Top + dropDownRect.Height / 2))
middle.X += (dropDownRect.Width Mod 2)
Dim arrowSmall As Point() = New Point() {New Point(middle.X - 2, middle.Y - 1), _
New Point(middle.X + 3, middle.Y - 1), _
New Point(middle.X, middle.Y + 2)}
Dim path As New Drawing2D.GraphicsPath()
path.AddRectangle(dropDownRect)
Dim lgb As New Drawing2D.LinearGradientBrush(path.GetBounds, m_ColorDark, m_Colorlight, 90, True)
If IsOpen Then
lgb.LinearColors = New Color() {m_ColorDark, m_Colorlight}
g.FillPath(lgb, path)
g.FillPolygon(New SolidBrush(Color.FromArgb(255, Color.White)), arrowSmall)
Else
lgb.LinearColors = New Color() {m_Colorlight, m_ColorDark}
g.FillPath(lgb, path)
g.FillPolygon(New SolidBrush(Color.FromArgb(255, Color.White)), arrowSmall)
End If
End Sub
Private Sub DrawLeftRectangle(ByVal g As Graphics, ByVal Rect As Rectangle)
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
Dim path As New Drawing2D.GraphicsPath()
path.AddRectangle(Rect)
Dim lgb As New Drawing2D.LinearGradientBrush(path.GetBounds, m_ColorDark, m_Colorlight, 90, True)
g.FillPath(lgb, path)
lgb.LinearColors = New Color() {m_Colorlight, m_ColorDark}
g.FillRectangle(lgb, New Rectangle(Rect.X, Rect.Y, Rect.Width, Rect.Height))
End Sub
Private Sub DrawText(ByVal g As Graphics)
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
g.DrawString(m_Text, Me.Font, New SolidBrush(Color.White), m_TextRect)
End Sub
Public Sub SizeDropDown()
If m_Control IsNot Nothing Then
m_Control.Location = New Point(m_TsDropDown.Padding.Left, m_TsDropDown.Padding.Top)
End If
End Sub
Public Sub CloseDropDown()
m_TsDropDown.Hide()
IsOpen = False
End Sub
Public Sub OpenDropDown()
If m_TsHost IsNot Nothing Then
m_Top = CShort(m_TextRect.Bottom + 2)
m_Left = CShort((Me.Width - m_TsHost.Width) / 2)
Dim tsd As ToolStripDropDownDirection = ToolStripDropDownDirection.BelowRight
Try
If Me.Location.Y + Me.Parent.Location.Y + m_Top + m_TsHost.Height > Screen.FromControl(Me).WorkingArea.Bottom - 10 Then
tsd = ToolStripDropDownDirection.AboveRight
End If
Catch ex As Exception
End Try
m_TsDropDown.Show(Me, New Point(m_Left, m_Top), tsd)
IsOpen = True
End If
End Sub
Public Sub ForceDropDownClose()
m_TsDropDown.Hide()
IsOpen = False
End Sub
Public Sub DropControl_Move(ByVal sender As Object, ByVal e As System.EventArgs)
SizeDropDown()
End Sub
Public Sub DropControl_Resize(ByVal sender As Object, ByVal e As System.EventArgs)
SizeDropDown()
End Sub
Public Sub ResizeMe()
IsResize = False
If Not IsOpen Then
Me.Region = Nothing
End If
IsResize = True
End Sub
Public Sub InvalidateRegion()
Me.Region = Nothing
Dim rgn As Region = New Region(New Rectangle(0, 0, Me.Width, Me.Height))
rgn.Union(New RectangleF(0, Me.Height, Me.PanelSize.Width, Me.PanelSize.Height))
Me.Region = rgn.Clone
rgn.Dispose()
End Sub
Public Sub tsdd_Open(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)
RaiseEvent OnDropDown(Me, True)
End Sub
Public Sub tsdd_Close(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripDropDownClosingEventArgs)
Try
If (Not GetDropDownButtonPath.IsVisible(PointToClient(Control.MousePosition)) Or (e.CloseReason = ToolStripDropDownCloseReason.Keyboard)) Then
IsOpen = False
End If
If Not e.Cancel Then
Invalidate()
RaiseEvent OnDropDown(Me, False)
End If
Catch ex As Exception
End Try
End Sub
#End Region
#Region "Function"
Public Function GetDropDownButtonPath() As Drawing2D.GraphicsPath
Dim path As New Drawing2D.GraphicsPath
path.AddRectangle(m_ButtonRect)
Return path
End Function
#End Region
#Region "Event"
Private Sub DropDownCalculator_ControlAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.ControlEventArgs) Handles Me.ControlAdded
If DesignMode And e.Control Is m_Control Then
RemoveHandler m_Control.Resize, AddressOf DropControl_Resize
RemoveHandler m_Control.Move, AddressOf DropControl_Move
m_Control = Nothing
End If
End Sub
Private Sub DropDownCalculator_HandleCreated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.HandleCreated
If Not DesignMode Then
If m_Control IsNot Nothing Then
m_TsHost = New ToolStripControlHost(m_Control)
m_TsHost.Margin = Padding.Empty
m_TsHost.Padding = Padding.Empty
m_TsHost.AutoSize = False
m_TsHost.Size = m_Control.Size
m_TsDropDown.AutoSize = False
m_TsDropDown.Size = m_TsHost.Size
m_TsDropDown.Items.Add(m_TsHost)
m_TsDropDown.BackColor = Color.Transparent
m_TsDropDown.Padding = New Padding(0)
m_TsDropDown.DropShadowEnabled = False
Me.Controls.Remove(m_Control)
End If
End If
End Sub
Private Sub DropDownCalculator_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
If e.Y < Me.Height Then
IsMouseDownButton = True
Invalidate(m_ButtonRect)
If Not DesignMode Then
If IsOpen Then
CloseDropDown()
Else
OpenDropDown()
End If
End If
End If
End If
End Sub
Private Sub DropDownCalculator_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
If IsMouseDownButton Then
IsMouseDownButton = False
End If
Invalidate(m_ButtonRect)
End Sub
Private Sub DropDownCalculator_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
Try
If Not DesignMode Then
ForceDropDownClose()
End If
If Me.FindForm.WindowState <> FormWindowState.Minimized And IsResize Then
ResizeMe()
End If
Catch ex As Exception
End Try
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
Dim g As Graphics = e.Graphics
Dim bounds As Rectangle = Me.ClientRectangle
m_ButtonRect = New Rectangle(bounds.Right - PushButtonWidth - 1, BorderSize, PushButtonWidth, bounds.Height - BorderSize * 2)
m_TextRect = New Rectangle(bounds.Left, BorderSize, bounds.Width - PushButtonWidth - 1, bounds.Height - BorderSize * 2)
DrawLeftRectangle(g, m_TextRect)
DrawText(g)
DrawArrow(g, m_ButtonRect)
End Sub
#End Region
End Class
أتمني إن الفكرة تعجبكم واعتقد أنه يمكنكم تطويرها والتعديل بها بما يتناسب مع احتياجاتكم
في المرفقات وبنسخة الفيجوال 2008 ستجدون مثال عن الألة الحاسبة المنسدلة ومثال اخر عن ساعة عقارب منسدلة
بالتوفيق
أخوكم عمر