.NET에서 TabControl을 마법사 스타일로 변환하는 방법은 무엇입니까?
-
12-09-2019 - |
문제
나는 마법사 스타일로 내 양식을 갖고 싶어서 TabControl을 사용하여 마법사의 페이지를 탭 페이지로 사용했습니다. 런타임에 탭을 표시하는 등의 작은 문제가 수정해야했습니다. TabControl을 상속하고 "TabsVisible"이라는 속성을 추가하여 수정했습니다. 잘 작동했습니다. (보다 : http://dotnetrix.co.uk/tabcontrol.htm - Hidetabs 속성을 추가하여 Tabitems를 켜거나 끕니다)
그러나 다음과 같은 다른 작은 문제가 있습니다. 1. Ctrl + 탭이 누르면 탭이 변경됩니다. OnkeyDown 방법 2를 재정의하여 비활성화됩니다. 활성 커서가 탭 목록에 있고 화살표 키를 누르면 현재 탭 페이지가 변경됩니다. 어떻게 이것을 비활성화 할 수 있습니까 ??
그래서 내 질문은 - 탭 페이지가 변경되지 않도록 탭 콘트롤에서 화살표 키를 비활성화 할 수있는 방법은 무엇입니까?
해결책 4
나는 다음과 같이했다. 선택한 탭이 코드에서 변경된 경우 플래그가있었습니다. 그렇다면 나는 그것을 허용했거나 그렇지 않으면 허용되지 않습니다. 다음 코드는 나에게 잘 작동했습니다.
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
다른 팁
즉, 탭 컨트롤이 필요하지 않습니다. 다른 마법사 단계에 대한 GUI를 포함하기 위해 패널을 사용하고 마법사가 스스로를 밟은 버튼이나 다른 것을 그만두고 모든 문제를 저장하지 않겠습니까? 그렇게하면 당신은이 모든 것을 자유롭게 할 수 있으며, 스타일을 지정할 수는 있지만 훨씬 더 단순하고 훨씬 더 유연합니다.
TabControl 페이지를 변경하여 화살표 키를 비활성화하려면 키 다운 이벤트를 처리하고 다음과 같은 작업을 수행 할 수 있습니다.
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;
}
따라서 기본적으로 프레스 키가 화살표 키 인 경우 이벤트를 처리 한 것으로 표시합니다.
WizardControl 프레임 워크를 만들었습니다. WizardFormbase를 사용합니다. Usercontrol 컬렉션으로 양식을로드합니다. 나머지는 자동으로 발생합니다. 이것은 다음 시리즈를 기반으로했습니다 ...
http://weblogs.asp.net/justin_rogers/articles/60155.aspx
제 1 조는 꽤 어리 석다 ... 그러나 그는 제 2 조에 의해 그것을 고칠 것이다.
나는 이것처럼 그것을 정확히하지 않았다. 여기에 내 비트가 있습니다. Telerik Controls 참조를 제거하고 실제 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
마법사
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 Designer 파일
<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
도움이 되었기를 바랍니다.
세스