Czy istnieje sposób na wyłączenie karty w TabControl ?
Odpowiedzi:
Tabpage klasa ukrywa Enabled właściwość. To było zamierzone, ponieważ występuje z nim niezręczny problem z projektem interfejsu użytkownika. Podstawowym problemem jest to, że wyłączenie strony nie wyłącza również zakładki. A jeśli spróbujesz obejść ten problem, wyłączając kartę ze zdarzeniem Selecting, to nie zadziała, gdy TabControl ma tylko jedną stronę.
Jeśli te problemy z użytecznością nie dotyczą Ciebie, pamiętaj, że właściwość nadal działa, jest po prostu ukryta przed IntelliSense. Jeśli FUD jest niewygodny, możesz po prostu zrobić to:
public static void EnableTab(TabPage page, bool enable) {
foreach (Control ctl in page.Controls) ctl.Enabled = enable;
}
Prześlij TabPage na Control, a następnie ustaw właściwość Enabled na false.
((Control)this.tabPage).Enabled = false;
Dlatego nagłówek zakładki będzie nadal włączony, ale jego zawartość będzie wyłączona.
Możesz po prostu użyć:
tabPage.Enabled = false;
Ta właściwość nie jest pokazana, ale działa bez żadnych problemów.
Zdarzenie Selecting można zaprogramować tak, TabControler
aby nie było możliwe przejście do nieedytowalnej zakładki:
private void tabControler_Selecting(object sender, TabControlCancelEventArgs e)
{
if (e.TabPageIndex < 0) return;
e.Cancel = !e.TabPage.Enabled;
}
Visible
właściwości, chociaż nie wydawało się, aby miało to żaden efekt wizualny, kiedy ją testowałem.
Możesz zarejestrować zdarzenie „Selecting” i anulować nawigację do strony zakładki:
private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
if (e.TabPage == tabPage2)
e.Cancel = true;
}
Innym pomysłem jest umieszczenie wszystkich kontrolek na karcie w kontrolce panelu i wyłączenie panelu! Smiley
Możesz także usunąć tabpage z kolekcji tabControl1.TabPages. To by ukryło zakładkę.
Kredyty trafiają do littleguru @ Channel 9 .
Przypuszczalnie chcesz widzieć kartę w kontrolce karty, ale chcesz, aby była „wyłączona” (tj. Wyszarzona i niewybieralna). Nie ma wbudowanej obsługi tego, ale możesz zastąpić mechanizm rysowania, aby uzyskać pożądany efekt.
Przykładem, jak to zrobić jest warunkiem tutaj .
Magia tkwi w tym fragmencie z prezentowanego źródła oraz w metodzie DisableTab_DrawItem:
this.tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
this.tabControl1.DrawItem += new DrawItemEventHandler( DisableTab_DrawItem );
Rozszerzanie na odpowiedź Cédrica Guillemette, po wyłączeniu Control
:
((Control)this.tabPage).Enabled = false;
... możesz wtedy obsłużyć zdarzenie TabControl
' Selecting
jako:
private void tabControl_Selecting(object sender, TabControlCancelEventArgs e)
{
e.Cancel = !((Control)e.TabPage).Enabled;
}
Spowoduje to usunięcie strony karty, ale w razie potrzeby będziesz musiał dodać ją ponownie:
tabControl1.Controls.Remove(tabPage2);
Jeśli będziesz go później potrzebować, możesz zechcieć go przechowywać na tymczasowej karcie przed usunięciem, a następnie ponownie dodać w razie potrzeby.
Jedynym sposobem jest złapanie Selecting
zdarzenia i zapobieżenie aktywacji karty.
Najtrudniejszym sposobem jest uczynienie jego rodzica równym null (zrób samą tabulator bez rodzica):
tabPage.Parent = null;
A kiedy zechcesz go zwrócić (zwróci go z powrotem na końcu zbioru stron):
tabPage.Parent = tabControl;
A jeśli chcesz zwrócić go z powrotem w określonej lokalizacji wśród stron, których możesz użyć:
tabControl.TabPages.Insert(indexLocationYouWant, tabPage);
Możesz to zrobić poprzez zakładki: tabPage1.Hide (), tabPage2.Show () itd.
tabControl.TabPages.Remove (tabPage1);
W przeszłości usuwałem karty, aby użytkownik nie mógł ich klikać. Prawdopodobnie nie jest to jednak najlepsze rozwiązanie, ponieważ może być konieczne sprawdzenie, czy strona karty istnieje.
Korzystając ze zdarzeń i właściwości kontrolki karty, możesz włączać / wyłączać to, co chcesz, kiedy chcesz. Użyłem jednego bool, który jest dostępny dla wszystkich metod w klasie formularza potomnego mdi, w której jest używany tabControl.
Pamiętaj, że zdarzenie wybierania jest uruchamiane za każdym razem, gdy klikniesz dowolną kartę. W przypadku dużej liczby kart „CASE” może być łatwiejsze w użyciu niż kilka „if”.
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;
}
}
}
Użytkownik nie może klikać kart, aby nawigować, ale może użyć dwóch przycisków ( Nexti Back). Użytkownik nie może przejść do następnej, jeśli warunki // nie są spełnione.
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;
}
Załóżmy, że masz te kontrolki:
TabControl o nazwie tcExemple.
TabPages o nazwach tpEx1 i tpEx2.
Spróbuj:
Ustaw DrawMode swojej TabPage na OwnerDrawFixed; Po InitializeComponent () upewnij się, że tpEx2 nie jest włączony, dodając ten kod:
((Control)tcExemple.TabPages["tpEx2").Enabled = false;
Dodaj do zdarzenia tcExemple zaznaczenie poniższy kod:
private void tcExemple_Selecting(object sender, TabControlCancelEventArgs e)
{
if (!((Control)e.TabPage).Enabled)
{
e.Cancel = true;
}
}
Dołącz do zdarzenia DrawItem w tcExemple ten kod:
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);
}
}
}
Spowoduje to, że druga karta nie będzie możliwa do kliknięcia.
To stare pytanie, ale ktoś może skorzystać na moim uzupełnieniu. Potrzebowałem TabControl, który wyświetlałby ukryte karty sukcesywnie (po wykonaniu akcji na bieżącej karcie). Utworzyłem więc szybką klasę do dziedziczenia i wywołałem HideSuccessive () podczas ładowania:
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();
}
w języku C # 7.0 dostępna jest nowa funkcja o nazwie Dopasowywanie wzorców . Możesz wyłączyć wszystkie karty za pomocą wzorca typu .
foreach (Control control in Controls)
{
// the is expression tests the variable and
// assigned it to a new appropriate variable type
if (control is TabControl tabs)
{
tabs.Enabled = false;
}
}
W przypadku ładowania formularza, jeśli napiszemy this.tabpage.PageEnabled = false
, zakładka zostanie wyłączona.
Rozwiązanie jest bardzo proste.
Usuń / skomentuj tę linię
this.tabControl.Controls.Add(this.YourTabName);
w metodzie IntializeComponent () w pliku MainForm.cs
Nie mogłem znaleźć odpowiedniej odpowiedzi na to pytanie. Wygląda na to, że nie ma rozwiązania umożliwiającego wyłączenie określonej karty. To, co zrobiłem, to przekazanie określonej zakładki do zmiennej i na SelectedIndexChanged
wypadek gdyby umieściłem ją z powrotem 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;
}
Tak więc w rzeczywistości nie wyłączasz karty, ale po kliknięciu innej karty zawsze powraca do wybranej karty.