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:
- WPF - reset ListBox scroll position when ItemsSource changes
- http://wizardsofsmart.net/uncategorized/itemssourcechanged-event-using-attached-dependency-properties/
- http://joshsmithonwpf.wordpress.com/2009/09/04/how-to-prevent-a-tabitem-from-being-selected/
- http://social.expression.microsoft.com/Forums/en-US/wpf/thread/f7b46018-1e97-4bbe-ada8-49b75dbc1da2/
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.
Czy wiemy, że jest to błąd w WPF? Czy może z jakiegoś dziwnego powodu "według projektu"? – skybluecodeflier
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 .. –