TabControl-阻止用户更改选定的选项卡:MessageBox导致错误

sky*_*ier 5 c# wpf xaml tabcontrol mvvm

我一直在讨论这个问题,并且只找到了部分解决方案.

我正在尝试设置TabControl,以便在某些情况下我可以阻止用户更改当前选定的选项卡.当阻止用户更改当前选定的选项卡时,将显示一个对话框.

我已经阅读了以下文件:

我已经实现了第3个链接中指示的解决方案(尽管以上所有内容都会产生相同的错误).它有效, ......

如果用户执行以下操作,事情就会彻底搞乱:

  • 尝试在不允许此类操作时更改选项卡.MessageBox弹出错误.
  • 用户单击"确定"并返回到原始窗口.
  • 用户再次尝试更改选项卡. 没有MessageBox出现.
  • 如果用户最小化窗口,然后再次最大化它,则出现应该出现的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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我正在使用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>
Run Code Online (Sandbox Code Playgroud)

为了简洁起见,我省略了其余的代码 - 支持窗口的是一个非常简单的ViewModel结构.

Fre*_*lad 5

正如您所注意到的,问题在于MessageBox事件处理程序内部.重点将改为MessageBox,你可以得到各种不受欢迎的效果.我有自己的问题.

以下是关于同一主题的几个问题
WPF:MessageBox Break PreviewMouseDown?
当MessageBox出现时,Wpf停止路由事件?

如果你必须向用户显示一条消息,那么另一种方法可能是创建一个Window你喜欢的样式的新方法MessageBox,然后在事件处理程序中调用Show(而不是 ShowDialog)它.