WPF选项卡控件阻止选项卡更改

我正在尝试为我的应用程序开发一个系统维护屏幕,其中我有几个选项卡,每个选项卡代表不同的维护选项,即维护系统用户等。 一旦用户点击edit / new来更改现有记录,我想阻止导航离开当前标签,直到用户点击保存或取消。

经过一些谷歌搜索后,我找到了一个链接http://joshsmithonwpf.wordpress.com/2009/09/04/how-to-prevent-a-tabitem-from-being-selected/这似乎解决了我的问题,或者左右我想。

我已经尝试过这个,但我的事件似乎永远不会发生。 下面是我的XAML。

            

这是我的代码

 public partial class SystemMaintenanceWindow : Window { private enum TEditMode { emEdit, emNew, emBrowse } private TEditMode _EditMode = TEditMode.emBrowse; private TEditMode EditMode { get { return _EditMode; } set { _EditMode = value; } } public SystemMaintenanceWindow() { InitializeComponent(); var view = CollectionViewSource.GetDefaultView(tabControl.Items.SourceCollection); view.CurrentChanging += this.Items_CurrentChanging; } void Items_CurrentChanging(object sender, CurrentChangingEventArgs e) { if ((e.IsCancelable) && (EditMode != TEditMode.emBrowse)) { var item = ((ICollectionView)sender).CurrentItem; e.Cancel = true; tabControl.SelectedItem = item; MessageBox.Show("Please Save or Cancel your work first.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } private void btnUsersNew_Click(object sender, RoutedEventArgs e) { EditMode = TEditMode.emNew; } private void btnUsersEdit_Click(object sender, RoutedEventArgs e) { EditMode = TEditMode.emEdit; } private void btnCancel_Click(object sender, RoutedEventArgs e) { EditMode = TEditMode.emBrowse; } } 

现在道歉,如果我是愚蠢的,但对于我的生活,我无法锻炼,看看为什么当用户在标签之间点击时我的事件不会触发。

感谢你的帮助。

埃姆林

我想出了一个适合我需求的解决方案。 似乎略微倒退,但与其他选项相比,我发现它看起来很漂亮。

基本上我保留当前tabIndex的私有变量和tabControl的“SelectionChanged”事件我正在做一些检查,如果用户不处于浏览模式,则将tabControl.SelectedIndex设置回此值。

 private void tabControl_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) { if (e.OriginalSource == tabControl) { if (EditMode == TEditMode.emBrowse) { _TabItemIndex = tabControl.SelectedIndex; } else if (tabControl.SelectedIndex != _TabItemIndex) { e.Handled = true; tabControl.SelectedIndex = _TabItemIndex; MessageBox.Show("Please Save or Cancel your work first.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } } 

我也在努力解决这个问题。 只需添加即可让它工作

 IsSynchronizedWithCurrentItem="True" 

设置为TabControl。 之后工作就像一个魅力。

Josh正在使用tab.ItemsSource 。 您正在使用tab.Items.SourceCollection 。 这可能是问题所在。

或者自己实施……

 public delegate void PreviewSelectionChangedEventHandler(object p_oSender, PreviewSelectionChangedEventArgs p_eEventArgs); public class PreviewSelectionChangedEventArgs { internal PreviewSelectionChangedEventArgs(IList p_lAddedItems, IList p_lRemovedItems) { this.AddedItems = p_lAddedItems; this.RemovedItems = p_lRemovedItems; } public bool Cancel { get; set; } public IList AddedItems { get; private set; } public IList RemovedItems { get; private set; } } public class TabControl2: TabControl { public event PreviewSelectionChangedEventHandler PreviewSelectionChanged; private int? m_lLastSelectedIndex; protected override void OnSelectionChanged(SelectionChangedEventArgs e) { base.OnSelectionChanged(e); // déterminer si on doit annuler la sélection PreviewSelectionChangedEventArgs eEventArgs = new PreviewSelectionChangedEventArgs(e.AddedItems, e.RemovedItems); if (m_lLastSelectedIndex.HasValue) if (PreviewSelectionChanged != null) PreviewSelectionChanged(this, eEventArgs); // annuler (ou pas) la sélection if (eEventArgs.Cancel) this.SelectedIndex = m_lLastSelectedIndex.Value; else m_lLastSelectedIndex = this.SelectedIndex; } } 

根据这篇文章

https://social.msdn.microsoft.com/Forums/vstudio/en-US/d8ac2677-b760-4388-a797-b39db84a7e0f/how-to-cancel-tabcontrolselectionchanged?forum=wpf

这对我有用:

        
 private void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (e.Source is TabItem) //do not handle clicks on TabItem content but on TabItem itself { var vm = this.DataContext as MyViewModel; if (vm != null) { if (!vm.CanLeave()) { e.Handled = true; } } } } 

我开始掌握XAML所以我希望我没有错过你的观点。 我遇到了同样的问题,对我而言这是最好的。

在XAML中,我定义了一个切换ReadOnly状态的Style

      

在viewmodel中我有一个属性

  private EditingState _PhysicianEditingState; public EditingState PhysicianEditingState { get { return _PhysicianEditingState; } set { _PhysicianEditingState = value; PhysicianTypeTabAreLocked = (PhysicianEditingState != EditingState.NotEditing); NotifyPropertyChanged("PhysicianTypeTabAreLocked"); } } 

希望这可以帮助。