我一直在冲击此问题一段时间,只找到部分解决方案。TabControl-阻止用户更改选定的选项卡:导致bug的MessageBox
我想设置一个TabControl,以便在某些情况下可以防止用户更改当前选定的选项卡。当阻止用户更改当前选择的选项卡时,会显示一个对话框。
我已经阅读了以下文件:
- 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/
我已经实现在第三链接指示的解决方案(尽管所有以上创建相同的错误s见下文)。和它的作品,但...
事情搞糟彻底如果用户执行以下操作:
- 企图改变标签时,这种行为是不允许的。 MessageBox随着错误弹出。
- 用户单击“确定”并返回到原始窗口。
- 用户再次尝试更改选项卡。 不显示消息框。
- 如果用户最小化窗口,然后再次最大化,那么出现应该出现的消息框。
- 用户单击“确定”并返回到原始窗口... ,但该标签已更改为之前选择的标签,即使它们不应该能够更改标签。
这很明显是不是的理想行为。 为什么MessageBox不会第二次出现,为什么当它不应该这样做时,标签会发生变化?
如果我删除MessageBox部分,它工作正常。
下面是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;
}
}
我使用MVVM来实现这一点。该窗口看起来是这样的:
<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>
我忽略了的brevity-缘故代码的其余部分有一个非常直接的视图模型结构支持的窗口。
我们知道这是否是WPF中的错误?还是出于某种奇怪的原因“按设计”? – skybluecodeflier
我不确定,在几年前找到了这个原因,但从未找到任何信息。只是用Reflector来看它,但它很复杂,以告诉发生了什么。 –