He estado hablando mucho sobre este tema por un tiempo, y solo he encontrado parte de la solución.TabControl - evitando que el usuario cambie la pestaña seleccionada: MessageBox causando el error
Estoy intentando configurar un TabControl para evitar, en algunos casos, que el usuario cambie la pestaña actualmente seleccionada. Cuando el usuario no puede cambiar la pestaña seleccionada actualmente, se le muestra un cuadro de diálogo.
que ya han leído los siguientes documentos:
- 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/
he implementado la solución indicada en la tercera enlace (aunque todos de los anteriores crean el mismo error m een abajo). Y funciona, pero ...
echar las cosas a fondo si el usuario hace lo siguiente:
- intentos de cambiar la pestaña cuando se ha anulado tal acción. El MessageBox aparece con el error.
- el usuario hace clic en "Aceptar" y regresa a la ventana original.
- el usuario intenta nuevamente cambiar la pestaña. No aparece MessageBox.
- si el usuario minimiza la ventana y luego la maximiza de nuevo, aparece el MessageBox que se suponía que debía aparecer antes.
- el usuario hace clic en "Aceptar" y regresa a la ventana original ... pero la pestaña se ha cambiado a la que seleccionaron antes, aunque no deberían poder cambiar las pestañas.
Esto es obviamente no comportamiento ideal. ¿Por qué no aparece el MessageBox por segunda vez, y por qué está cambiando la pestaña cuando no debería permitirse?
Si elimino la parte de MessageBox, funciona bien.
Este es el código del controlador de eventos 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;
}
}
estoy usando MVVM para implementar esto. La ventana se ve así:
<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>
estoy omitiendo el resto del código en aras de brevity- hay una estructura modelo de vista bastante recta hacia adelante el respaldo de la ventana.
¿Sabemos si esto es un error en WPF? ¿O es por alguna extraña razón "por diseño"? – skybluecodeflier
No estoy seguro, busqué la razón de esto hace un par de años pero nunca encontré ninguna información. Acabo de verlo con Reflector pero es complejo decir qué está pasando. –