2011-09-06 16 views
5

Od pewnego czasu próbuję rozwiązać ten problem i znalazłem tylko część rozwiązania.TabControl - uniemożliwiając użytkownikowi zmianę wybranej karty: MessageBox powodujący błąd

Próbuję skonfigurować TabControl, aby w niektórych przypadkach uniemożliwić użytkownikowi zmianę aktualnie wybranej karty. Gdy użytkownik nie może zmienić aktualnie wybranej karty, zostaną wyświetlone okna dialogowe.

już zapoznać się z następującymi dokumentami:

I wprowadziły rozwiązania wskazanego w 3 linku (choć wszystko z powyższych utworzyć ten sam błąd s poniżej). I to działa, ale...

Things bałagan dokładnie wtedy, gdy użytkownik wykonuje następujące operacje:

  • próby, aby zmienić kartę, gdy takie działanie jest niedozwolone. MessageBox pojawia się z błędem.
  • użytkownik klika "OK" i powraca do oryginalnego okna.
  • użytkownik próbuje ponownie zmienić zakładkę. Nie pojawia się komunikat MessageBox.
  • jeśli użytkownik zminimalizuje okno, a następnie zmaksymalizuje go ponownie, pojawi się komunikat MessageBox, który miał pojawić się wcześniej.
  • użytkownik kliknie "OK" i powróci do oryginalnego okna ... , ale karta została zmieniona na tę, którą wybrała wcześniej, mimo że nie można zmieniać kart.

To jest oczywiście nie idealne zachowanie. Dlaczego MessageBox nie pojawia się po raz drugi i dlaczego karta zmienia się, kiedy nie wolno tego robić?

Po usunięciu części MessageBox działa poprawnie.

Oto kod do obsługi zdarzeń TabControl.SelectionChanged:

bool _isChanging = false; 

    private void tabControlForNavigation_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (!_isChanging && canChangeTabs.IsChecked.HasValue) 
     { 
      _isChanging = true; 


      bool canLeave = canChangeTabs.IsChecked.Value; //normally this would be replaced by a check in the ViewModel 

      if (!canLeave) 
      { 
       int prevIndex = tabControlForNavigation.Items.IndexOf(tabControlForNavigation.SelectedContent); 
       tabControlForNavigation.SelectedIndex = prevIndex; 
       MessageBox.Show("Can't change tabs!"); //if I comment out this line, everything works fine. 
      } 

      _isChanging = false; 
     } 
    } 

Używam MVVM do wdrożenia tego. Okno wygląda następująco:

<Window x:Class="TestTabControlSwitching.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" 
    Height="350" 
    Width="525"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition /> 
    </Grid.RowDefinitions> 
    <CheckBox x:Name="canChangeTabs" 
       Content="Can Change Tabs" 
       IsChecked="True" /> 
    <TabControl x:Name="tabControlForNavigation" 
       Grid.Row="1" 
       IsSynchronizedWithCurrentItem="True" 
       ItemsSource="{Binding Collection}" 
       SelectedItem="{Binding SelectedItem}" 
       SelectionChanged="tabControlForNavigation_SelectionChanged" 
       Margin="4" 
       HorizontalAlignment="Stretch"> 
     <TabControl.ItemTemplate> 
      <DataTemplate> 
       <ContentPresenter Content="{Binding Path=Name}" /> 
      </DataTemplate> 
     </TabControl.ItemTemplate> 

    </TabControl> 
</Grid> 

Ja pomijając resztę kodu dla dobra brevity- jest dość prosta konstrukcja ViewModel kopii okno.

Odpowiedz

5

Jak zauważyłeś, problemem jest MessageBox wewnątrz procedury obsługi zdarzeń. Ostrość zmieni się na MessageBox i możesz uzyskać wszelkiego rodzaju niepożądane efekty. Miałem swoje własne problemy z tym.

Oto kilka SO pytanie w tej samej sprawie
WPF: Does MessageBox Break PreviewMouseDown?
Wpf stop routing event when MessageBox appear?

Jeśli trzeba wyświetlić wiadomość do użytkownika a następnie zastępca podejście może być stworzenie nowego Window który You styl niczym MessageBox, a następnie zadzwoń pod numer Show (notShowDialog) wewnątrz programu obsługi zdarzeń.

+0

Czy wiemy, że jest to błąd w WPF? Czy może z jakiegoś dziwnego powodu "według projektu"? – skybluecodeflier

+0

Nie jestem pewien, szukałem tego powodu kilka lat temu, ale nigdy nie znalazłem żadnych informacji. Wystarczy spojrzeć na to z Reflectorem, ale to jest skomplikowane, aby powiedzieć, co się dzieje .. –

+0

No cóż. Twoja praca dookoła nie jest idealna, ale wykonalna. Niestety muszę mieć jakieś wyskakujące okienko. – skybluecodeflier

0

Znam ten post jest trochę stary, ale mam bardzo prosty sposób do osiągnięcia tego celu:

Użyj zdarzenie tab_Enter i stworzyć metodę, która wykonuje swój czek i wyświetla MessageBox dla użytkownika, a następnie ustaw myTabs.SelectedIndex do poprzedniego indeksu. Prosty przykład:

private void someTab_Enter(object sender, EventArgs e) 
    { 
     if (myCondition) 
     { 
      MessageBox.Show("Sorry, myCondition will not let you move to this tab."); 
      myTabs.SelectedIndex = someOtherTabIndex; 
     } 
    } 
0

To było bardzo szczegółowe pytanie. Miałem ten sam problem, który miałeś (tzn. Okno komunikatu nie wyświetlało się na 2. lub 3. wyborze, dopóki nie zminimalizowałeś i nie zmaksymalizował okna) i po wielu debugowaniach i wielu wyszukiwaniach w Google, natknąłem się na poniższy link posta na forum MSDN.

[TabControl SelectionChanged Strange Behaviour?]

proszę ignorować źle sformatowaną pytanie i odpowiedź. Ale jak wspomniano w odpowiedzi, umieszczenie go wewnątrz dyspozytora i skupienie się na wybranej zakładce po ustawieniu indeksu rozwiązało problem dla mnie.

0

Brakuje łatwej sztuczki. Po prostu ustaw ostrość = False dla nagłówka Tab.

<TabItem Header="MY TAB" Focusable="False"> 

Można powiązać tę właściwość z modelem widoku.

<TabItem Header="MY TAB" Focusable="{Binding Bool_CanHasCheeseBurger}"> 
Powiązane problemy