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; } }
根据这篇文章
这对我有用:
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"); } }
希望这可以帮助。