-1

I am currently working on a just for fun solution for myself, to create workout plans for the gym. Solution on Github

It is a simple WPF solution using Caliburn.Micro to easier get the connections for the MVVM pattern.

On my MainView I have a TabControl:

MainView.xaml:

<TabControl x:Name="Items" />

With the following code for the ViewModel:

 public MainViewModel()
    {     
      DisplayName = "Plan2Fit";
      Items.Add(new CreatePlanViewModel(_exerciseProviderViewModel));
      Items.Add(new ExerciseManagementViewModel(_exerciseProviderViewModel));
    }

I only have two ViewModels displayed in the TabControl, one to manage exercises and store them in xml to have kind of a database of your exercises and one where you should later be able to pick exercises for your plan.

Problem: At startup everything looks ok, but as soon as I switch between the Tabs, one of them might loose its child control for whatever reason.

I have already tried the following:

MainView.xaml:

<TabControl x:Name="Items"  cal:Message.Attach="[Event SelectionChanged] = [Action Reload]" />

MainViewModel:

public void Reload()
{
  _exerciseProviderViewModel = new ExerciseProviderViewModel();
  Items.Refresh();
  DisplayName = "Plan2Fit";
}

This makes the error happen less often but it still is existing.

I have already found this question ... the solutions I was able to find are all working with MVVM, but not with Caliburn.Micro, so I am really not havinmg any Idea, how to solve this. I have tried Avalon dock, but I was not able to get it to work with the Caliburn way of binding x:Name="Items"

Note: If you want to recreate the Bug using my solution, you have to add some "Exercises" by picking an image in the "Manage Exercise" tab and click Add (You can add the same "Exercise" multiple times). There is no errorhandling or testing done so far, as this is at the state where I want to validate, if it works at all.

christian
  • 110
  • 1
  • 2
  • 15
  • Does `MainViewModel` inherit from `Conductor.Collection.OneActive`? You don't need to switch the items yourself, that is handled by Caliburn Micro for you. It will activate and de-activate your tabs as necessary. If you search [this](https://caliburnmicro.com/documentation/composition) page for `TabControl` it has an example that shows how to do it. – Jack Hughes Aug 28 '18 at 10:28

1 Answers1

0

I found the problem, still I dont understand, why it is a problem at all.

Given:

public MainViewModel()
{     
  DisplayName = "Plan2Fit";
  Items.Add(new CreatePlanViewModel(_exerciseProviderViewModel));
  Items.Add(new ExerciseManagementViewModel(_exerciseProviderViewModel));
}

The tabcontrol will occasionally loose its childs. If I pass a new ExerciseProviderViewModel into eacht Items.Add() call, the bug does not occur. Thus I stored a ExerciseProvider as member and passed this one into my ViewModels I want to add.

 public MainViewModel()
{
  _exerciseProvider = new ExerciseProvider(new DCSerializer<List<Exercise>>());
  DisplayName = "Plan2Fit";
  ActivateItem(new CreatePlanViewModel(new ExerciseProviderViewModel(_exerciseProvider)));
  ActivateItem(new ExerciseManagementViewModel(new ExerciseProviderViewModel(_exerciseProvider)));
}

This works without any problems.

christian
  • 110
  • 1
  • 2
  • 15