D-moE
D-moE

Reputation: 1

WPF Programmatically changing tab sort of work, but I have to click the tab again to able to click away

I have a BackstageViewControl menu creating tabs that load a new view for each tab selected. One of the views has a form that, in the event they click another tab, I want to prompt the user letting them know they have unsaved changes, would you still like to leave. If they click yes, then it navigates to the next page like normal, if no it stays on the current view. I've managed to get most of this concept to work, however, I have this strange problem where once you click cancel, I programmatically set the tab to remain the current one to prevent the navigation. Once I do that, clicks of the other tabs don't even register. I have to click the current tab, then it will allow me to navigate away like normal. It's as if the view I want is displaying, but the tab of the other is selected, but I have no idea how to get them to match.

My View:

<dxr:RibbonControl.ApplicationMenu>
    <views:MyBackstageViewControl
        x:Name="bvcMenu"
        BackgroundGlyphStyle="{StaticResource myGlyphStyle}"
        IsOpen="{Binding IsBackstageOpen}"
        ItemsSource="{Binding BackstageItems}"
        SelectedTabIndex="0"/>
</dxr:RibbonControl.ApplicationMenu>
<dxr:RibbonDefaultPageCategory Caption="defaultCategory" />

I had to override the OnSelectedTabChanged in the control because SelectedTabChanged was changing my view before the prompt was answered.

 public class MyBackstageViewControl : BackstageViewControl
 {
     public BackstageTabItem Old { get; set; }
     private readonly IEventAggregator _eventAggregator;
     private MainWindowViewModel ViewModel 
     { 
         get => (MainWindowViewModel)DataContext; 
         set => DataContext = value; 
     }

     public MyBackstageViewControl()
         : base()
     {
         _eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();

     }
     protected override void OnSelectedTabChanged(BackstageTabItem oldValue)
     {

         if (oldValue != null && oldValue.Content as string == "Routing Settings")
         {
             Old = oldValue;
             _eventAggregator.GetEvent<OldBackstageTab>()
                 .Publish(oldValue.Content as string);
             _eventAggregator.GetEvent<ConfirmNavigationEvent>()
                 .Subscribe(OnNavigationConfirmed);
         }
         else
         {
             base.OnSelectedTabChanged(oldValue);
         }
     }

     private void OnNavigationConfirmed(bool confirmed)
     {
         if (confirmed)
         {
             base.OnSelectedTabChanged(Old);
         }
         else
         {
             this.SelectedTab = Old;
         }
     }
 }

I'm using the event aggregators because the tabs are a part of the Main Window view and the Dialog window needs to populate centered in the other view.

I've tried coming up with a way to programmatically click the tab once after to just trigger it, but I'd rather it not have to be clicked at all.

Upvotes: 0

Views: 43

Answers (0)

Related Questions