Gibt es eine Möglichkeit, einen Tab in einem TabControl zu deaktivieren?
Ich verwende C #.
Die TabPage -Klasse verbirgt die Enabled-Eigenschaft. Dies war beabsichtigt, da es ein unangenehmes UI-Designproblem gibt. Das grundlegende Problem ist, dass das Deaktivieren der Seite die Registerkarte nicht auch deaktiviert. Und wenn Sie versuchen, dies zu umgehen, indem Sie die Registerkarte mit dem Ereignis Selecting deaktivieren, funktioniert es nicht, wenn das TabControl nur eine Seite hat.
Wenn diese Usability-Probleme Sie nicht betreffen, denken Sie daran, dass die Eigenschaft weiterhin funktioniert. Sie wird lediglich vor IntelliSense verborgen. Wenn die FUD unangenehm ist, können Sie dies einfach tun:
public static void EnableTab(TabPage page, bool enable) {
foreach (Control ctl in page.Controls) ctl.Enabled = enable;
}
Wandeln Sie Ihre TabPage in ein Steuerelement um, und setzen Sie die Enabled-Eigenschaft auf false.
((Control)this.tabPage).Enabled = false;
Daher ist die Kopfzeile der Registerkarte weiterhin aktiviert, ihr Inhalt wird jedoch deaktiviert.
Sie können einfach verwenden:
tabPage.Enabled = false;
Diese Eigenschaft wird nicht angezeigt, funktioniert jedoch problemlos.
Sie können das Selecting-Ereignis auf TabControler
programmieren, um den Wechsel zu einer nicht bearbeitbaren Registerkarte nicht zu ermöglichen:
private void tabControler_Selecting(object sender, TabControlCancelEventArgs e)
{
if (e.TabPageIndex < 0) return;
e.Cancel = !e.TabPage.Enabled;
}
Sie können das Ereignis "Auswählen" registrieren und die Navigation zur Registerseite abbrechen:
private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
if (e.TabPage == tabPage2)
e.Cancel = true;
}
Eine andere Idee ist, alle Steuerelemente auf der Registerkarte eines Panel-Steuerelements zu platzieren und das Panel zu deaktivieren! Smiley
Sie können die Registerkarte auch aus der tabControl1.TabPages-Auflistung entfernen. Das würde die Registerkarte ausblenden.
Credits gehen nach littleguru @ Channel 9 .
Vermutlich möchten Sie die Registerkarte in der Registerkarte sehen, aber "deaktiviert" (d. H. Grau und nicht auswählbar). Es gibt keine integrierte Unterstützung dafür, aber Sie können den Zeichenmechanismus überschreiben, um den gewünschten Effekt zu erzielen.
Ein Beispiel dafür ist hier bereitgestellt .
Die Magie befindet sich in diesem Ausschnitt aus der präsentierten Quelle und in der DisableTab_DrawItem-Methode:
this.tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
this.tabControl1.DrawItem += new DrawItemEventHandler( DisableTab_DrawItem );
Nach der Antwort von Cédric Guillemette erweitern, nachdem Sie die Control
deaktiviert haben:
((Control)this.tabPage).Enabled = false;
... können Sie das Ereignis TabControl
der Variable Selecting
folgendermaßen behandeln:
private void tabControl_Selecting(object sender, TabControlCancelEventArgs e)
{
e.Cancel = !((Control)e.TabPage).Enabled;
}
Dadurch wird die Registerkarte entfernt, Sie müssen sie jedoch bei Bedarf erneut hinzufügen:
tabControl1.Controls.Remove(tabPage2);
Wenn Sie es später benötigen, können Sie es vor dem Entfernen auf einer temporären Registerkarte speichern und bei Bedarf erneut hinzufügen.
Die einzige Möglichkeit ist, das Selecting
-Ereignis abzufangen und zu verhindern, dass ein Tab aktiviert wird.
Ich musste vor einiger Zeit damit umgehen. Ich habe das Tab aus der TabPages-Sammlung entfernt (ich denke, das war es) und es wieder hinzugefügt, wenn sich die Bedingungen geändert haben. Das war aber nur in Winforms, wo ich die Übersicht behalten konnte, bis ich es wieder brauchte.
Sie können dies über die Registerkarten tun: tabPage1.Hide (), tabPage2.Show () usw.
Am schwierigsten ist es, wenn das übergeordnete Element gleich null ist (das Register allein ohne das übergeordnete Element festlegen):
tabPage.Parent = null;
Und wenn Sie es zurückgeben möchten (wird am Ende der Seitenauflistung zurückgegeben):
tabPage.Parent = tabControl;
Und wenn Sie es an einem bestimmten Ort zwischen den Seiten zurückgeben möchten, können Sie Folgendes verwenden:
tabControl.TabPages.Insert(indexLocationYouWant, tabPage);
tabControl.TabPages.Remove (tabPage1);
Ich habe in der Vergangenheit Registerkarten entfernt, um zu verhindern, dass der Benutzer auf sie klickt. Dies ist jedoch wahrscheinlich nicht die beste Lösung, da möglicherweise die Registerseite vorhanden ist.
antwort von rfnodulator für Vb.Net:
Private Sub TabControl1_Selecting(sender As Object, e As TabControlCancelEventArgs) Handles TabControl1.Selecting
e.Cancel = Not e.TabPage.Enabled
End Sub
Ich habe dieses Problem wie folgt gelöst: Ich habe 3 Registerkarten und möchte den Benutzer auf der ersten Registerkarte behalten, wenn er sich nicht angemeldet hat
if (condition) { TabControl.Deselect("2ndPage"); TabControl.Deselect("3dPage"); }
Mit Hilfe von Ereignissen und den Eigenschaften der Registerkarte können Sie aktivieren und deaktivieren, wann Sie möchten. Ich habe ein Bool verwendet, das für alle Methoden in der untergeordneten Formularklasse mdi verfügbar ist, in der das tabControl verwendet wird.
Denken Sie daran, dass das Auswahlereignis jedes Mal ausgelöst wird, wenn auf eine Registerkarte geklickt wird. Bei einer großen Anzahl von Registerkarten ist ein "CASE" möglicherweise einfacher zu verwenden als eine Reihe von Ifs.
public partial class Form2 : Form
{
bool formComplete = false;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
formComplete = true;
tabControl1.SelectTab(1);
}
private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
if (tabControl1.SelectedTab == tabControl1.TabPages[1])
{
tabControl1.Enabled = false;
if (formComplete)
{
MessageBox.Show("You will be taken to next tab");
tabControl1.SelectTab(1);
}
else
{
MessageBox.Show("Try completing form first");
tabControl1.SelectTab(0);
}
tabControl1.Enabled = true;
}
}
}
Die Lösung ist sehr einfach.
Diese Zeile entfernen/kommentieren
this.tabControl.Controls.Add(this.YourTabName);
in der IntializeComponent () - Methode in MainForm.cs
Angenommen, Sie haben folgende Steuerelemente:
TabControl mit dem Namen tcExemple.
TabPages mit den Namen tpEx1 und tpEx2.
Versuch es:
Setzen Sie DrawMode von TabPage auf OwnerDrawFixed; Stellen Sie nach InitializeComponent () sicher, dass tpEx2 nicht aktiviert ist.
((Control)tcExemple.TabPages["tpEx2").Enabled = false;
Fügen Sie der Auswahl tcExemple-Ereignis den folgenden Code hinzu:
private void tcExemple_Selecting(object sender, TabControlCancelEventArgs e)
{
if (!((Control)e.TabPage).Enabled)
{
e.Cancel = true;
}
}
An DrawItem-Ereignis von tcExemple diesen Code anhängen:
private void tcExemple_DrawItem(object sender, DrawItemEventArgs e)
{
TabPage page = tcExemple.TabPages[e.Index];
if (!((Control)page).Enabled)
{
using (SolidBrush brush = new SolidBrush(SystemColors.GrayText))
{
e.Graphics.DrawString(page.Text, page.Font, brush, e.Bounds);
}
}
else
{
using (SolidBrush brush = new SolidBrush(page.ForeColor))
{
e.Graphics.DrawString(page.Text, page.Font, brush, e.Bounds);
}
}
}
Dadurch wird die zweite Registerkarte nicht anklickbar.
Der Benutzer kann nicht auf Registerkarten klicken, um zu navigieren, sondern die beiden Schaltflächen verwenden (Next und Back). Der Benutzer kann nicht mit dem nächsten fortfahren, wenn die // Bedingungen nicht erfüllt sind.
private int currentTab = 0;
private void frmOneTimeEntry_Load(object sender, EventArgs e)
{
tabMenu.Selecting += new TabControlCancelEventHandler(tabMenu_Selecting);
}
private void tabMenu_Selecting(object sender, TabControlCancelEventArgs e)
{
tabMenu.SelectTab(currentTab);
}
private void btnNextStep_Click(object sender, EventArgs e)
{
switch(tabMenu.SelectedIndex)
{
case 0:
//if conditions met GoTo
case 2:
//if conditions met GoTo
case n:
//if conditions met GoTo
{
CanLeaveTab:
currentTab++;
tabMenu.SelectTab(tabMenu.SelectedIndex + 1);
if (tabMenu.SelectedIndex == 3)
btnNextStep.Enabled = false;
if (btnBackStep.Enabled == false)
btnBackStep.Enabled = true;
CannotLeaveTab:
;
}
private void btnBackStep_Click(object sender, EventArgs e)
{
currentTab--;
tabMenu.SelectTab(tabMenu.SelectedIndex - 1);
if (tabMenu.SelectedIndex == 0)
btnBackStep.Enabled = false;
if (btnNextStep.Enabled == false)
btnNextStep.Enabled = true;
}
Ich konnte keine passende Antwort auf die Frage finden. Es scheint keine Lösung zu geben, um die bestimmte Registerkarte zu deaktivieren. Was ich getan habe, ist, die spezifische Registerkarte an eine Variable zu übergeben und in SelectedIndexChanged
event auf SelectedIndex
zurückzusetzen:
//variable for your specific tab
int _TAB = 0;
//here you specify your tab that you want to expose
_TAB = 1;
tabHolder.SelectedIndex = _TAB;
private void tabHolder_SelectedIndexChanged(object sender, EventArgs e)
{
if (_TAB != 0) tabHolder.SelectedIndex = _TAB;
}
Sie deaktivieren die Registerkarte also nicht, aber wenn Sie auf eine andere Registerkarte klicken, werden Sie immer zur ausgewählten Registerkarte zurückkehren.