Hello. I am implementing an app based on the MVVM pattern. One of my controls has a dockmanager with a tabgrouppane. I need to be able to change the active tab based on a property in my viewmodel. Here's what the xaml looks like:
ObjectDataProvider def:
<Window.Resources> <ResourceDictionary>
<ObjectDataProvider x:Key="odpWizard" ObjectType="{x:Type ViewModel:WizardViewModel}" IsAsynchronous="True" />...
TabGroupPane def:
<igDock:TabGroupPane x:Name="tabGroup1" SelectionChanged="tabGroup1_SelectionChanged" DataContext="{Binding Source={StaticResource odpWizard}}" SelectedIndex="{Binding ActiveTab}">...
ViewModel def;
private int _activeTab;
public int ActiveTab { get { return _activeTab; } set { _activeTab = value; OnPropertyChanged("ActiveTab"); } }
What I'm missing is how to change the active tab from the ViewModel. Thanks for the help.
byronking said:Hmmm... Maybe I don't want to use this control given your last comment. I wasn't aware of the "CTRL" navigation. Does the igWindows:XamTabControl not allow for this?
byronking said: I don't really need to show all the tabs because I am controlling the flow of the "wizard". Do you recommend only adding tabs to the igWindows:XamTabControl as the user completes each section? On the other hand, if I use only one tab in the igWindows:XamTabControl how do you recommend I represent the "wizard" flow?
Hmmm... Maybe I don't want to use this control given your last comment. I wasn't aware of the "CTRL" navigation. Does the igWindows:XamTabControl not allow for this? I don't really need to show all the tabs because I am controlling the flow of the "wizard". Do you recommend only adding tabs to the igWindows:XamTabControl as the user completes each section? On the other hand, if I use only one tab in the igWindows:XamTabControl how do you recommend I represent the "wizard" flow?
Then its probably because you have keyboard focus in the first pane and simply changing the selected index will not take focus from that pane and we need to keep the active pane (i.e.the one with the keyboard focus) in view. If I may ask, why do you want to use a TabGroupPane for this? It would seem to me that you would want this to be treated as a single entity and not as indvidual pages. As we discussed earlier you wouldn't want to be able to unpin/float/close an individual pane. Also if this is a wizard then you wouldn't want the user to see each pane in the tab group - e.g. when they for example press Ctrl-Tab and see the pane navigator they will see each contentpane in the control which in this case will mean they will see each step/page/tab of the wizard or when they press Alt-F7 which cycles through the contentpanes. If you want the whole wizard to be one pane so that it may be floated/unpinned/closed as a unit that is fine - then I would say you should use a TabControl or something else as the wizard and put that by itself into a ContentPane but I'm not sure I understand why you want to use separate contentpanes as the steps/pages/tabs of the wizard.
Thanks again for the quick response. Allow me to briefly describe what I'm trying to do. I have a tabgrouppane in a user control with 6 tabs(let's call this my wizard control). A user entering the app goes to the first tab and enters data (companyname and companydesc) and then clicks "Next". If the validation for the fields passes, the tab to the right of the current active tab should become focused. I have a validator class for each tab because each tab corresponds to a separate viewmodel. Each viewmodel has an instance of its validator and vice versa. The validator also has access to the wizard control via a wizardviewmodel. I am able to set the ActiveTab property form the validator below, but that change isn't reflected in the tabgrouppane. Here is the validator code:
public class CompanyValidator { private CompanyViewModel companyViewModel { get; set; } private WizardViewModel wizardViewModel { get; set; } public CompanyValidator(CompanyViewModel cvm) { this.companyViewModel = cvm; } #region Public Methods public void Validate() { ObservableCollection<ValidationFailure> localValidationErrors = new ObservableCollection<ValidationFailure>(); #region Validate Company if (companyViewModel.Name == String.Empty) { localValidationErrors.Add(new ValidationFailure("CompanyName", Properties.Resources.EmptyCompanyNameString)); } if (companyViewModel.Description == String.Empty) { localValidationErrors.Add(new ValidationFailure("CompanyDesc", Properties.Resources.EmptyCompanyDescString)); } #endregion companyViewModel.ValidationErrors = localValidationErrors; if (localValidationErrors.Count > 0) { StringBuilder sb = new StringBuilder(); foreach (var error in localValidationErrors) { sb.AppendLine(error.Description); } MessageBox.Show(sb.ToString()); } else { // Save the company. companyViewModel.Save(); wizardViewModel.SetActiveTab(1); // Hard-coded to the next tab for a test. } } #endregion }
So the SetActiveTab method doesn't result in the selection changing? Again it could be that if focus is within the previously selected tab then we would keep that as the selected item. I'm not sure what you mean by changing it from another user control but if that means that focus was elsewhere then that could be why it worked. I would probably need to see a sample to actually understand what you are trying and why it is failing. One thing that I can say is that the relaycommand seems incorrect. It looks like your SetActiveTabCommand is always going to use whatever was the selectedTab integer passed into the constructor which I'm assuming is not what you want. I might have thought that you would use the CommandParameter as the index that you want to activate unless you're exposing one command per tab/pane.