Как преобразовать TabControl в стиль мастера в .NET? - PullRequest
0 голосов
/ 13 июля 2009

Я хочу, чтобы моя форма была в стиле мастера, поэтому я использовал TabControl, чтобы страницы мастера были моими страницами TabPages. Были небольшие проблемы, которые нужно было исправить, например, отображение вкладок во время выполнения. Я унаследовал TabControl и добавил свойство «TabsVisible» и исправил его. Работало нормально. (См .: http://dotnetrix.co.uk/tabcontrol.htm - добавить свойство HideTabs для включения / выключения Tabitems)

Но есть и другие мелкие проблемы, такие как: 1. При нажатии Ctrl + Tab вкладки меняются. Это отключено путем переопределения метода OnKeyDown 2. Когда активный курсор находится в списке вкладок и нажаты клавиши со стрелками, текущая страница вкладки изменяется. Как я могу отключить это ??

Итак, мой вопрос - Как отключить клавиши со стрелками в tabControl, чтобы страница вкладки не изменялась?

Ответы [ 4 ]

1 голос
/ 13 июля 2009

Другими словами: вам не нужен вкладка управления. Почему бы вам просто не использовать Панели для графического интерфейса пользователя для различных шагов мастера и кнопок или чего-то еще в качестве шагов мастера и избавить себя от всех этих проблем? Таким образом, вы будете свободны от всего этого, И сможете стилизовать его так, как считаете нужным - гораздо проще и гораздо гибче.

0 голосов
/ 24 июля 2009

Я сделал это следующим образом. Был флаг, если выбранная вкладка изменялась из кода. Если так, то я позволил это или иначе это запрещено. Следующий код работал нормально для меня.

    Private _selectedTabBeingChangedFromCode As Boolean

    Private Function IsDesignMode() As Boolean
        Return Me.Site IsNot Nothing AndAlso Me.Site.DesignMode = True
    End Function

    Public Shadows Property SelectedTab() As System.Windows.Forms.TabPage
        Get
            Return MyBase.SelectedTab
        End Get
        Set(ByVal value As System.Windows.Forms.TabPage)
            _selectedTabBeingChangedFromCode = True
            MyBase.SelectedTab = value
            _selectedTabBeingChangedFromCode = False
        End Set
    End Property

    Private Sub WizardTabControl_Selecting(ByVal sender As Object, ByVal e As System.Windows.Forms.TabControlCancelEventArgs) Handles Me.Selecting
        If IsDesignMode() Then
            Return
        End If

        If _selectedTabBeingChangedFromCode = False Then
            e.Cancel = True
        End If
    End Sub
0 голосов
/ 14 июля 2009

Я создал фреймворк WizardControl. Он использует wizardFormBase. Вы загружаете форму с коллекцией UserControl. Остальное происходит автоматически. Это было основано на следующих сериях ...

http://weblogs.asp.net/justin_rogers/articles/60155.aspx

Статья 1 довольно глупа ... но он исправляет это статьей 2.

Я не делал это точно так. Вот мои биты для этого. Вам придется удалить ссылки на элементы управления telerik и заменить действительными ссылками на элементы управления winforms.

Вы устанавливаете UIRoot, который в основном является панельным элементом управления (или любым другим контейнерным элементом управления) для загрузки страниц. Страницы - это USerControls, но вы можете изменить это для размещения любого типа элемента управления.

Imports System.Windows
Imports System.ComponentModel
Imports System.Windows.Forms


Public Interface IWizardDialog
    ReadOnly Property NavigatePrevious() As Control
    ReadOnly Property NavigateNext() As Control
    ReadOnly Property NavigateFinish() As Control
    ReadOnly Property NavigateCancel() As Control
    ReadOnly Property UIRoot() As Control
    Property Display() As Boolean
End Interface
Public Interface IWizardUserControl
    ReadOnly Property ShowNavigatePrevious() As Boolean
    ReadOnly Property ShowNavigateNext() As Boolean
    ReadOnly Property ShowNavigateFinish() As Boolean
    ReadOnly Property ShowNavigateCancel() As Boolean
    ReadOnly Property Description() As String
    ReadOnly Property StepCaption() As String
End Interface

Public Class WizardController
    Private _complete As Boolean = False
    Private _wizardIndex As Integer = -1
    Private _wizardDialog As IWizardDialog
    Private _wizardUserControls As New ArrayList()

    Private _allowClose As Boolean = False

    Public Sub SetDialog(ByVal dialog As Form)
        _wizardDialog = TryCast(dialog, IWizardDialog)
        If _wizardDialog Is Nothing Then
            Throw New Exception("Wizard must support IWizardDialog interface")
        Else

            If _wizardDialog.NavigatePrevious Is Nothing Then Throw New Exception("Wizard Dialogs must have a previous button.")
            If _wizardDialog.NavigateNext Is Nothing Then Throw New Exception("Wizard Dialogs must have a next button.")
            If _wizardDialog.NavigateFinish Is Nothing Then Throw New Exception("Wizard Dialogs must have a finish button.")
            If _wizardDialog.NavigateCancel Is Nothing Then Throw New Exception("Wizard Dialogs must have a cancel button.")
            If _wizardDialog.UIRoot Is Nothing Then Throw New Exception("Wizard Dialog must have a  non null UI Container.")
        End If

        AddHandler _wizardDialog.NavigatePrevious.Click, AddressOf Wizard_NavigatePrevious
        AddHandler _wizardDialog.NavigateNext.Click, AddressOf Wizard_NavigateNext
        AddHandler _wizardDialog.NavigateFinish.Click, AddressOf Wizard_NavigateFinish
        AddHandler _wizardDialog.NavigateCancel.Click, AddressOf Wizard_Cancel
        AddHandler dialog.Closing, AddressOf Me.Wizard_Closing

    End Sub

    Public Sub AddUserControl(ByVal ctrl As UserControl)
        Dim vUserControl As IWizardUserControl = TryCast(ctrl, IWizardUserControl)
        If vUserControl Is Nothing Then Throw New Exception("UserControl must implement IWizardUserControl interface.")
        _wizardUserControls.Add(ctrl)
    End Sub

    Public Sub StartWizard()
        If _wizardUserControls.Count = 0 Then
            Throw New Exception("Must add dialogs to the wizard")
        End If
        If _wizardIndex <> -1 AndAlso Not _complete Then
            Throw New Exception("Wizard has already been started")
        End If

        _complete = False

        _wizardIndex = 0

        Try
            Dim startControl As UserControl = DirectCast(_wizardUserControls(_wizardIndex), UserControl)
            InitUserControl(startControl)
        Catch ex As Exception
            'do nothing
        End Try
        _wizardDialog.Display = True

    End Sub
    Public Sub InitUserControl(ByVal wizardUserControl As UserControl)

        wizardUserControl.Dock = DockStyle.Fill

        Try
            Dim iwp As IWizardUserControl = DirectCast(wizardUserControl, IWizardUserControl)

            _wizardDialog.NavigatePrevious.Enabled = iwp.ShowNavigatePrevious
            _wizardDialog.NavigateNext.Enabled = iwp.ShowNavigateNext
            _wizardDialog.NavigateFinish.Enabled = iwp.ShowNavigateFinish
            _wizardDialog.NavigateCancel.Enabled = iwp.ShowNavigateCancel
            TryCast(_wizardDialog, Form).Text = iwp.StepCaption

        Catch
            ' Do Nothing
        End Try

        _wizardDialog.UIRoot.Controls.Clear()
        _wizardDialog.UIRoot.Controls.Add(wizardUserControl)

    End Sub

    Public Sub Wizard_Closing(ByVal Sender As Object, ByVal E As CancelEventArgs)
        If _allowClose = False Then
            MessageBox.Show("You must complete the wizard in order to exit.")
            E.Cancel = True
        End If
    End Sub

    Private Sub CloseWizard(Optional ByVal diagResult As DialogResult = DialogResult.Cancel)
        'allows closing of wizard
        _wizardDialog.UIRoot.Controls.Clear()
        _complete = True
        _allowClose = True
        TryCast(_wizardDialog, Form).DialogResult = diagResult
    End Sub

    Public Sub Wizard_NavigateNext(ByVal sender As Object, ByVal e As EventArgs)
        _wizardIndex += 1

        If _wizardIndex = _wizardUserControls.Count Then
            CloseWizard()
            ' This shouldn't happen if your dialogs are correct
            Exit Sub
        End If

        Try
            Dim nextControl As UserControl = DirectCast(_wizardUserControls(_wizardIndex), UserControl)
            InitUserControl(nextControl)
        Catch ex As Exception
            'do nothing
        End Try

    End Sub

    Public Sub Wizard_NavigatePrevious(ByVal sender As Object, ByVal e As EventArgs)
        If _wizardIndex > 0 Then
            Try
                Dim newControl As UserControl = DirectCast(_wizardUserControls(_wizardIndex - 1), UserControl)
                InitUserControl(newControl)
                _wizardIndex -= 1
            Catch
                ' Do Nothing
            End Try
        End If
    End Sub

    Public Sub Wizard_NavigateFinish(ByVal sender As Object, ByVal e As EventArgs)
        ' this could be fired anywhere in case you have an opt out
        ' early button on any of your forms.

        CloseWizard(DialogResult.OK)

    End Sub

    Public Sub Wizard_Cancel(ByVal sender As Object, ByVal e As EventArgs)
        'put cancel code here
        'if needed put validation to see if cancel is allowed.  But generally you will allow cancel.
        CloseWizard()
    End Sub

    Public ReadOnly Property Complete() As Boolean
        Get
            Return _complete
        End Get
    End Property

    Public ReadOnly Property UserControls() As ArrayList
        Get
            Return _wizardUserControls
        End Get
    End Property
    Public ReadOnly Property WizardDialog() As IWizardDialog
        Get
            Return _wizardDialog
        End Get
    End Property


End Class

WizardFormBase

Imports System.Windows.Forms
Imports Telerik.WinControls.UI



''' <summary>
''' WizardFormBase
''' </summary>
''' <remarks></remarks>
Public Class WizardFormBase
    Implements IWizardDialog

    Private _title As String = String.Empty

    ''' <summary>
    ''' Initializes a new instance of the WizardFormBase class.
    ''' </summary>
    Public Sub New(ByVal title As String)

        _title = title
        InitializeComponent()

    End Sub

    Public ReadOnly Property NavigateCancel() As System.Windows.Forms.Control Implements IWizardDialog.NavigateCancel
        Get
            Return RadBtn_Cancel
        End Get
    End Property

    Public ReadOnly Property NavigateFinish() As System.Windows.Forms.Control Implements IWizardDialog.NavigateFinish
        Get
            Return RadBtn_Finish
        End Get
    End Property

    Public ReadOnly Property NavigateNext() As System.Windows.Forms.Control Implements IWizardDialog.NavigateNext
        Get
            Return RadBtn_Next
        End Get
    End Property

    Public ReadOnly Property NavigatePrevious() As System.Windows.Forms.Control Implements IWizardDialog.NavigatePrevious
        Get
            Return RadBtn_Previous
        End Get
    End Property

    Public Property Display() As Boolean Implements IWizardDialog.Display
        Get
            Return Me.Visible
        End Get
        Set(ByVal value As Boolean)
            If value = True Then Me.ShowDialog()
        End Set
    End Property

    Public ReadOnly Property UIRoot() As System.Windows.Forms.Control Implements IWizardDialog.UIRoot
        Get
            Return Me.mainPanel
        End Get
    End Property
End Class

Файл конструктора WizardFormBase

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class WizardFormBase
    Inherits FormBase

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing AndAlso components IsNot Nothing Then
            components.Dispose()
        End If
        MyBase.Dispose(disposing)
    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.RadBtn_Next = New Telerik.WinControls.UI.RadButton
        Me.RadBtn_Cancel = New Telerik.WinControls.UI.RadButton
        Me.RadBtn_Finish = New Telerik.WinControls.UI.RadButton
        Me.RadBtn_Previous = New Telerik.WinControls.UI.RadButton
        Me.pnlSetupWizardFormButtom = New Telerik.WinControls.UI.RadPanel
        Me.mainPanel = New System.Windows.Forms.Panel
        CType(Me.RadBtn_Next, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.RadBtn_Cancel, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.RadBtn_Finish, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.RadBtn_Previous, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.pnlSetupWizardFormButtom, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.pnlSetupWizardFormButtom.SuspendLayout()
        Me.SuspendLayout()
        '
        'RadBtn_Next
        '
        Me.RadBtn_Next.Location = New System.Drawing.Point(436, 13)
        Me.RadBtn_Next.Name = "RadBtn_Next"
        Me.RadBtn_Next.Size = New System.Drawing.Size(75, 23)
        Me.RadBtn_Next.TabIndex = 0
        Me.RadBtn_Next.Text = "Next >>"
        Me.RadBtn_Next.ThemeName = "Office2007Silver"
        '
        'RadBtn_Cancel
        '
        Me.RadBtn_Cancel.Location = New System.Drawing.Point(25, 13)
        Me.RadBtn_Cancel.Name = "RadBtn_Cancel"
        Me.RadBtn_Cancel.Size = New System.Drawing.Size(75, 23)
        Me.RadBtn_Cancel.TabIndex = 2
        Me.RadBtn_Cancel.Text = "Cancel"
        Me.RadBtn_Cancel.ThemeName = "Office2007Silver"
        '
        'RadBtn_Finish
        '
        Me.RadBtn_Finish.Location = New System.Drawing.Point(791, 13)
        Me.RadBtn_Finish.Name = "RadBtn_Finish"
        Me.RadBtn_Finish.Size = New System.Drawing.Size(75, 23)
        Me.RadBtn_Finish.TabIndex = 3
        Me.RadBtn_Finish.Text = "Finish"
        Me.RadBtn_Finish.ThemeName = "Office2007Silver"
        '
        'RadBtn_Previous
        '
        Me.RadBtn_Previous.Location = New System.Drawing.Point(355, 13)
        Me.RadBtn_Previous.Name = "RadBtn_Previous"
        Me.RadBtn_Previous.Size = New System.Drawing.Size(75, 23)
        Me.RadBtn_Previous.TabIndex = 1
        Me.RadBtn_Previous.Text = "<< Previous"
        Me.RadBtn_Previous.ThemeName = "Office2007Silver"
        '
        'pnlSetupWizardFormButtom
        '
        Me.pnlSetupWizardFormButtom.BackColor = System.Drawing.Color.Transparent
        Me.pnlSetupWizardFormButtom.Controls.Add(Me.RadBtn_Cancel)
        Me.pnlSetupWizardFormButtom.Controls.Add(Me.RadBtn_Next)
        Me.pnlSetupWizardFormButtom.Controls.Add(Me.RadBtn_Previous)
        Me.pnlSetupWizardFormButtom.Controls.Add(Me.RadBtn_Finish)
        Me.pnlSetupWizardFormButtom.Dock = System.Windows.Forms.DockStyle.Bottom
        Me.pnlSetupWizardFormButtom.Location = New System.Drawing.Point(1, 623)
        Me.pnlSetupWizardFormButtom.Name = "pnlSetupWizardFormButtom"
        Me.pnlSetupWizardFormButtom.Size = New System.Drawing.Size(898, 46)
        Me.pnlSetupWizardFormButtom.TabIndex = 1
        Me.pnlSetupWizardFormButtom.TabStop = False
        Me.pnlSetupWizardFormButtom.ThemeName = "ControlDefault"
        '
        'mainPanel
        '
        Me.mainPanel.Dock = System.Windows.Forms.DockStyle.Fill
        Me.mainPanel.Location = New System.Drawing.Point(1, 24)
        Me.mainPanel.Name = "mainPanel"
        Me.mainPanel.Size = New System.Drawing.Size(898, 599)
        Me.mainPanel.TabIndex = 5
        '
        'WizardFormBase
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(900, 670)
        Me.ControlBox = False
        Me.Controls.Add(Me.mainPanel)
        Me.Controls.Add(Me.pnlSetupWizardFormButtom)
        Me.KeyPreview = True
        Me.MaximizeBox = False
        Me.MaximumSize = New System.Drawing.Size(900, 700)
        Me.MinimizeBox = False
        Me.MinimumSize = New System.Drawing.Size(575, 325)
        Me.Name = "WizardFormBase"
        Me.ShowIcon = False
        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        Me.Text = "Setup Wizard"
        Me.Controls.SetChildIndex(Me.pnlSetupWizardFormButtom, 0)
        Me.Controls.SetChildIndex(Me.mainPanel, 0)
        CType(Me.RadBtn_Next, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.RadBtn_Cancel, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.RadBtn_Finish, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.RadBtn_Previous, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.pnlSetupWizardFormButtom, System.ComponentModel.ISupportInitialize).EndInit()
        Me.pnlSetupWizardFormButtom.ResumeLayout(False)
        Me.pnlSetupWizardFormButtom.PerformLayout()
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub
    Friend WithEvents RadBtn_Next As Telerik.WinControls.UI.RadButton
    Friend WithEvents RadBtn_Cancel As Telerik.WinControls.UI.RadButton
    Friend WithEvents RadBtn_Finish As Telerik.WinControls.UI.RadButton
    Friend WithEvents RadBtn_Previous As Telerik.WinControls.UI.RadButton
    Friend WithEvents pnlSetupWizardFormButtom As Telerik.WinControls.UI.RadPanel
    Friend WithEvents mainPanel As System.Windows.Forms.Panel
End Class

Надеюсь, это поможет.

Сет

0 голосов
/ 13 июля 2009

Чтобы запретить клавише со стрелкой изменять страницу вашего TabControl, вы можете обработать событие KeyDown и сделать что-то вроде этого:

private void tabControl_KeyDown(object sender, KeyEventArgs e)
{
    bool isArrowKey = e.KeyCode == Keys.Up || e.KeyCode == Keys.Down ||
                      e.KeyCode == Keys.Left || e.KeyCode == Keys.Right;

    e.Handled = isArrowKey;
}

Таким образом, вы помечаете событие как обработанное, если нажатая клавиша является клавишей со стрелкой.

...