我在SO上找到了多个关于这个问题的问题,但是我仍然无法得到一个可靠的解决方案。在阅读答案后,这是我想出的解决方案。
Xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="300" Width="300" x:Name="this">
<TabControl IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Tabs, ElementName=this}" x:Name="TabControl"/>
</Window>
代码后台:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var tabs = new ObservableCollection<string> {"Tab1", "Tab2", "Tab3"};
Tabs = CollectionViewSource.GetDefaultView(tabs);
Tabs.CurrentChanging += OnCurrentChanging;
Tabs.CurrentChanged += OnCurrentChanged;
Tabs.MoveCurrentToFirst();
CurrentTab = tabs.First();
}
private void OnCurrentChanging(object sender, CurrentChangingEventArgs e)
{
//only show message box when tab is changed by user input
if (!_cancelTabChange)
{
if (MessageBox.Show("Change tab?", "Message", MessageBoxButton.YesNo) == MessageBoxResult.No)
{
_cancelTabChange = true;
return;
}
}
_cancelTabChange = false;
}
private void OnCurrentChanged(object sender, EventArgs e)
{
if (!_cancelTabChange)
{
//Update current tab property, if user did not cancel transition
CurrentTab = (string)Tabs.CurrentItem;
}
else
{
//navigate back to current tab otherwise
Dispatcher.BeginInvoke(new Action(() => Tabs.MoveCurrentTo(CurrentTab)));
}
}
public string CurrentTab { get; set; }
public static readonly DependencyProperty TabsProperty = DependencyProperty.Register("Tabs", typeof(ICollectionView), typeof(MainWindow), new FrameworkPropertyMetadata(default(ICollectionView)));
public ICollectionView Tabs
{
get { return (ICollectionView)GetValue(TabsProperty); }
set { SetValue(TabsProperty, value); }
}
private bool _cancelTabChange;
}
基本上,我想在用户导航到不同的选项卡时显示确认消息,并且如果他点击“否” - 中止转换。但是,这段代码不起作用。如果您在“Tab2”上多次单击,每次在消息框中选择“否”,则在某个时候它会停止工作:事件停止触发。如果您单击“Tab3”,事件将再次触发,但是如果您选择“是”,它将打开第二个选项卡,而不是第三个。我有困难弄清楚正在发生什么。:)
有人看到我的解决方案中的错误吗?还是有更简单的方法来显示确认消息,当用户切换选项卡时?我也愿意使用任何具有适当
SelectionChanging
事件的开源选项卡控件。但我找不到任何一个。我正在使用.Net 4.0。
编辑: 如果我注释掉消息框:
private void OnCurrentChanging(object sender, CurrentChangingEventArgs e)
{
//only show message box when tab is changed by user input
if (!_cancelTabChange)
{
//if (MessageBox.Show("Change tab?", "Message", MessageBoxButton.YesNo) == MessageBoxResult.No)
//{
Debug.WriteLine("Canceled");
_cancelTabChange = true;
return;
//}
}
_cancelTabChange = false;
}
一切都正常运作。奇怪。