Custom DateTimePicker   otázka

VB.NET, Komponenty, WinForms

Zdravím, obracím se s radou pro windowsforms aplikaci.

U controlu DateTimePicker (VS2005) postrádám zobrazení

čísel týdnů a možnost skrýt či zobrazit Dnes podle toho,

zda-li se v povoleném intervalu nachází či nikoliv, taky

nechci využít možnost editace datumu přímo v textboxu,

ale pouze pomocí dropdown části s kalendářem.

Pokouším se podědit Label a do něj vložit dropdownbutton

poděděný z Controlu s vykresleným tlačítkem se šipkou

pomocí ComboBoxRenderer.DrawDropDownButton. Vložené tlačítko

může získat focus nastavením ControlStyles.Selectable

a po získání focusu pomocí tabulátoru rozbalit MonthCalendar

nebo se zobrazí část s kalendářem pomocí tlačítka myši.

Nyní se dostávám k zobrazení MonthCalendar jako popup, podobně

jako třeba u comboboxu, ale netuším, jak vytvořit dropdown

část s kalendářem, zřejmě podědit z formuláře nebo nějakého

containeru a do něj pak potřebný control (MonthCalendar) vložit.

Nevíte, prosím, jak na to?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Děláte to zbytečně složitě a výsledek bude buď nulový, nebo naprosto neuspokojivý. Když už potřebujete něco takového (o praktickém využití místo obyčejného DateTimePickeru mám velké pochybnosti), vytvořte klasický UserControl, ve kterém budou naskládané potřebné ovládací prvky.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Díky za Vaši pádnou nekompromisní odpověď, vážím si

Vaší samojediné reakce

Stále ale netuším, jak se poprat s dropdown částí?

UserControl má pak měnit svoji velikost, aby zobrazil

dropdown část? Co když bude control v Panelu nebo TabPage,

kde celý zobrazit nepůjde?

Neříkám, že to musí vždy být kalendář, vložený prvek

v dropdown části třeba i listview či datagridview,

půjde vybírat dle více sloupců, seřadit si je apod.

Jako příklad mi datetimepicker připadl nejlepší,

zajímá mě jak a z čeho popup část obecně vytvořít.

...

Zobrazení čísel týdnů a možnost skrýt či zobrazit Dnes :

http://www.tech-archive.net/Archive/DotN...

Varianta přímo pro DateTimePicker...

Bude to fungovat v 32bit i 64bit?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zkouším tip využít ToolStripDropDown, ale při více

formulářích mám problém udržet dropdown část aniž

by focus nepřebral jiný formulář, nastavit Parent

na rodičovský form controlu nepomohlo, kdyby někdo

věděl, jak s tím, tak by to pro moji potřebu zcela

uspokojivě splnilo požadavek pro začátek, je dost

věcí, co tam lze ještě doplnit, nebude-li lepší tip,

zkusím s tím dál pracovat, je to jen prvopokus.

Díky za další tip, radu i projevy soustrasti.

Public Class DatePickerBox
    Inherits Label
    Private WithEvents ddb As New DropDownButton
    Private WithEvents mc As New MonthCalendar
    Private WithEvents popup As New ToolStripDropDown
    
    Class DropDownButton
        Inherits Control
        Public Event DropDown(ByVal sender As Object)
        Private buttonState As System.Windows.Forms.VisualStyles.ComboBoxState = _
            System.Windows.Forms.VisualStyles.ComboBoxState.Normal
        Public Sub New()
            MyBase.New()
            SetStyle(ControlStyles.OptimizedDoubleBuffer _
                Or ControlStyles.UserPaint Or ControlStyles.Opaque, True)
        End Sub
        Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs)
            MyBase.OnKeyDown(e)
            If e.KeyCode = Keys.F4 Then
                RaiseEvent DropDown(Me)
            End If
        End Sub
        Protected Overrides Sub OnMouseLeave(ByVal e As System.EventArgs)
            MyBase.OnMouseLeave(e)
            buttonState = System.Windows.Forms.VisualStyles.ComboBoxState.Normal
            Invalidate()
        End Sub
        Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
            MyBase.OnMouseDown(e)
            If Me.Enabled Then
                If e.Button = MouseButtons.Left AndAlso Me.ClientRectangle.Contains(e.Location) Then
                    buttonState = System.Windows.Forms.VisualStyles.ComboBoxState.Pressed
                    Invalidate()
                End If
            End If
        End Sub
        Protected Overrides Sub OnMouseEnter(ByVal e As EventArgs)
            MyBase.OnMouseEnter(e)
            If Me.Enabled Then buttonState = System.Windows.Forms.VisualStyles.ComboBoxState.Hot
            Invalidate()
        End Sub
        Protected Overrides Sub OnMouseUp(ByVal e As MouseEventArgs)
            MyBase.OnMouseUp(e)
            buttonState = System.Windows.Forms.VisualStyles.ComboBoxState.Normal
            Invalidate()
        End Sub
        ' Detect when the cursor leaves the button area while it is pressed
        Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
            MyBase.OnMouseMove(e)
            ' Detect when the left mouse button is down and   
            ' the cursor has left the pressed button area. 
            If (e.Button And MouseButtons.Left) = MouseButtons.Left And Not _
                Me.ClientRectangle.Contains(e.Location) And _
                buttonState = System.Windows.Forms.VisualStyles.ComboBoxState.Pressed Then
                OnMouseLeave(e)
            End If
        End Sub
        Protected Overrides Sub OnMouseClick(ByVal e As System.Windows.Forms.MouseEventArgs)
            MyBase.OnMouseClick(e)
            If Me.Enabled Then RaiseEvent DropDown(Me)
        End Sub
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            e.Graphics.DrawString(Me.Text, Me.Font, SystemBrushes.WindowText, 0, 0)
            MyBase.OnPaint(e)
            If Not ComboBoxRenderer.IsSupported Then
                ControlPaint.DrawComboButton(e.Graphics, Me.ClientRectangle, Windows.Forms.ButtonState.Normal)
            Else
                ComboBoxRenderer.DrawDropDownButton(e.Graphics, Me.ClientRectangle, buttonState)
            End If
        End Sub
    End Class

    Public Sub New()
        MyBase.New()

        Dim w As Integer = SystemInformation.VerticalScrollBarWidth
        ddb.Size = New Size(w, Me.Height)
        ddb.Dock = DockStyle.Right
        Me.Controls.Add(ddb)

        mc.MaxSelectionCount = 1

        Me.TextAlign = ContentAlignment.MiddleLeft
        Me.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
        Me.BackColor = SystemColors.Window
        Me.Text = mc.SelectionStart.ToShortDateString

        popup.Margin = Padding.Empty
        popup.Padding = Padding.Empty
        Dim host As ToolStripControlHost = New ToolStripControlHost(mc)
        host.Margin = Padding.Empty
        host.Padding = Padding.Empty
        popup.Items.Add(host)
        popup.BackColor = Color.AliceBlue
        'popup.Parent = Me.FindForm '?
    End Sub

    Private Sub OnShowDropDown()
        If popup.Visible Then
            popup.Hide()
        Else
            Dim o As Object = Me.Parent
            Dim p As Point = New Point(Me.Left, Me.Bottom)
            While Not Me.FindForm Is o
                p.X = p.X + o.Left
                p.Y = p.Y + o.Top
                o = o.Parent
            End While
            popup.Show(Me.FindForm.PointToScreen(p))
        End If
    End Sub

    Private Sub mc_DateChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DateRangeEventArgs) Handles mc.DateChanged
        Me.Text = mc.SelectionStart.ToShortDateString
        Me.Invalidate()
    End Sub

    Private Sub mc_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles mc.KeyDown
        If Not (e.Alt Or e.Control Or e.Shift) And e.KeyCode = Keys.Enter Then
            popup.Hide()
            e.Handled = True
        ElseIf e.Control And e.KeyCode = Keys.Home Then
            mc.SelectionStart = Now.Date
            e.Handled = True
        End If
    End Sub

    Private Sub mc_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles mc.LostFocus
        Me.OnShowDropDown()
    End Sub

    Protected Overrides Sub Finalize()
        popup.Dispose()
        mc.Dispose()
        MyBase.Finalize()
    End Sub

    Private Sub popup_Closed(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripDropDownClosedEventArgs) Handles popup.Closed
        ddb.Enabled = True
    End Sub

    Private Sub popup_Opened(ByVal sender As Object, ByVal e As System.EventArgs) Handles popup.Opened
        ddb.Enabled = False
        mc.Focus()
    End Sub

    Private Sub ddb_DropDown(ByVal sender As Object) Handles ddb.DropDown
        Me.OnShowDropDown()
    End Sub

    Private Sub ddb_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles ddb.GotFocus
        SendKeys.Send("{F4}")
    End Sub
End Class

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Chci se dostat k události Paint, potřebuji barevně zvýraznit svátky v MonthCalendar,ale i přes nastavení SetStyle na UserPaint

se událost nevyvolá, v horším případě se kalendář dokonce ani nevykreslí, bude v tom nějaký zádrhel, že tento control prostě

Paint nevyvolá, místo toho OnPrint, ale to nefunguje. Nevíte?

Ohledně státních svátků to asi většinou řešíte vlastním seznamem plus funkcí na výpočet velikonočního pondělí, ale není možnost to nějak vyčíst z FW přes CultureInfo, pak Holidays nebo tak něco? Je to tak nadupaný, že to tam bude někde zašitý... :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Modifying the Windows Forms MonthCalendar control

http://nickeandersson.blogs.com/blog/200...

http://stackoverflow.com/questions/20730...

http://social.msdn.microsoft.com/Forums/...

Jak se dostat k události Paint :

Protected Shared WM_PAINT As Integer = &HF
            Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
                MyBase.WndProc(m)
                If m.Msg = WM_PAINT Then
                    Dim g As Graphics = Graphics.FromHwnd(Me.Handle)
                    Dim pe As New PaintEventArgs(g, New Rectangle(0, 0, Me.Width, Me.Height))
                    OnPaint(pe)
                End If
            End Sub

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback