Gibt es eine Möglichkeit, einen Tab in einem TabControl zu deaktivieren ?
Gibt es eine Möglichkeit, einen Tab in einem TabControl zu deaktivieren ?
Antworten:
Die TabPage- Klasse verbirgt die Enabled-Eigenschaft. Das war beabsichtigt, da es ein unangenehmes UI-Designproblem gibt. Das grundlegende Problem ist, dass durch Deaktivieren der Seite nicht auch die Registerkarte deaktiviert wird. Wenn Sie versuchen, dies zu umgehen, indem Sie die Registerkarte mit dem Auswahlereignis deaktivieren, funktioniert dies nicht, wenn das TabControl nur eine Seite enthält.
Wenn Sie diese Usability-Probleme nicht betreffen, denken Sie daran, dass die Eigenschaft weiterhin funktioniert. Sie ist 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;
}
Verwandeln Sie Ihre TabPage in ein Steuerelement und setzen Sie die Enabled-Eigenschaft auf false.
((Control)this.tabPage).Enabled = false;
Daher ist der Header der Registerkarte weiterhin aktiviert, der Inhalt jedoch deaktiviert.
Sie können einfach verwenden:
tabPage.Enabled = false;
Diese Eigenschaft wird nicht angezeigt, funktioniert jedoch problemlos.
Sie können das Auswahlereignis so programmieren TabControler
, dass kein Wechsel zu einer nicht bearbeitbaren Registerkarte möglich ist:
private void tabControler_Selecting(object sender, TabControlCancelEventArgs e)
{
if (e.TabPageIndex < 0) return;
e.Cancel = !e.TabPage.Enabled;
}
Visible
Eigenschaft zu gelten, obwohl es beim Testen keinen visuellen Effekt zu haben schien.
Sie können das Ereignis "Auswählen" registrieren und die Navigation zur Registerkarte 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 in ein Bedienfeld-Steuerelement einzufügen und das Bedienfeld zu deaktivieren! Smiley
Sie können die Registerkarte auch aus der tabControl1.TabPages-Auflistung entfernen. Das würde die Registerkarte verbergen.
Credits gehen an littleguru @ Channel 9 .
Vermutlich möchten Sie die Registerkarte im Registersteuerelement sehen, aber Sie möchten, dass sie "deaktiviert" ist (dh 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 finden Sie hier .
Die Magie liegt 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 );
Erweitern Sie die Antwort von Cédric Guillemette, nachdem Sie Folgendes deaktiviert haben Control
:
((Control)this.tabPage).Enabled = false;
... Sie können dann der Griff TabControl
s‘ Selecting
Ereignis als:
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, möchten Sie es möglicherweise vor dem Entfernen auf einer temporären Registerkarte speichern und bei Bedarf erneut hinzufügen.
Die einzige Möglichkeit besteht darin, das Selecting
Ereignis abzufangen und zu verhindern, dass eine Registerkarte aktiviert wird.
Der schwierigste Weg ist, das übergeordnete Element auf null zu setzen (machen Sie den Tab allein ohne übergeordnetes Element):
tabPage.Parent = null;
Und wenn Sie es zurückgeben möchten (wird es am Ende der Seitensammlung zurückgeben):
tabPage.Parent = tabControl;
Und wenn Sie es an einer bestimmten Stelle auf den Seiten zurückgeben möchten, können Sie Folgendes verwenden:
tabControl.TabPages.Insert(indexLocationYouWant, tabPage);
Sie können dies über die Registerkarten tun: tabPage1.Hide (), tabPage2.Show () usw.
tabControl.TabPages.Remove (tabPage1);
Ich habe in der Vergangenheit Registerkarten entfernt, um zu verhindern, dass der Benutzer darauf klickt. Dies ist jedoch wahrscheinlich nicht die beste Lösung, da sie möglicherweise sehen müssen, dass die Registerkarte vorhanden ist.
Mithilfe von Ereignissen und den Eigenschaften des Registersteuerelements können Sie aktivieren / deaktivieren, was Sie möchten, wann Sie möchten. Ich habe einen Bool verwendet, der für alle Methoden in der untergeordneten mdi-Formularklasse 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. Für eine große 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;
}
}
}
Ich habe dieses Problem folgendermaßen gelöst: Ich habe 3 Registerkarten und möchte den Benutzer auf der ersten Registerkarte belassen, wenn er sich nicht angemeldet hat, also auf dem SelectingEvent von TabControl, das ich geschrieben habe
if (condition) { TabControl.Deselect("2ndPage"); TabControl.Deselect("3dPage"); }
Der Benutzer kann nicht auf Registerkarten klicken, um zu navigieren, aber er kann die beiden Schaltflächen ( Nextund Back) verwenden. 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;
}
rfnodulator Antwort 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
Angenommen, Sie haben diese Steuerelemente:
TabControl mit dem Namen tcExemple.
Registerkarten mit den Namen tpEx1 und tpEx2.
Versuch es:
Setzen Sie den DrawMode Ihrer TabPage auf OwnerDrawFixed. Stellen Sie nach InitializeComponent () sicher, dass tpEx2 nicht aktiviert ist, indem Sie diesen Code hinzufügen:
((Control)tcExemple.TabPages["tpEx2").Enabled = false;
Fügen Sie der Auswahl tcExemple den folgenden Code hinzu:
private void tcExemple_Selecting(object sender, TabControlCancelEventArgs e)
{
if (!((Control)e.TabPage).Enabled)
{
e.Cancel = true;
}
}
An DrawItem-Ereignis von tc anhängen 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.
Dies ist eine alte Frage, aber jemand kann von meiner Hinzufügung profitieren. Ich brauchte ein TabControl, das nacheinander ausgeblendete Registerkarten anzeigt (nachdem eine Aktion auf der aktuellen Registerkarte ausgeführt wurde). Also habe ich eine schnelle Klasse zum Erben erstellt und HideSuccessive () beim Laden aufgerufen:
public class RevealingTabControl : TabControl
{
private Action _showNextRequested = delegate { };
public void HideSuccessive()
{
var tabPages = this.TabPages.Cast<TabPage>().Skip(1);
var queue = new ConcurrentQueue<TabPage>(tabPages);
tabPages.ToList().ForEach(t => t.Parent = null);
_showNextRequested = () =>
{
if (queue.TryDequeue(out TabPage tabPage))
tabPage.Parent = this;
};
}
public void ShowNext() => _showNextRequested();
}
Wenn wir this.tabpage.PageEnabled = false
im Formularladeereignis schreiben , wird die Registerkarte deaktiviert.
Die Lösung ist sehr einfach.
Diese Zeile entfernen / kommentieren
this.tabControl.Controls.Add(this.YourTabName);
in der IntializeComponent () -Methode in MainForm.cs
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 sie im SelectedIndexChanged
Ereignis zurückzusetzen auf SelectedIndex
:
//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 wirklich, aber wenn Sie auf eine andere Registerkarte klicken, kehren Sie immer zur ausgewählten Registerkarte zurück.