0

I am trying to make a program in MVVM which can read Excel files and generate the content into a Word file. Now I am stuck at making new Tabs on a UserControl, every time someone chooses to create a Word file on the checkbox:

MainWindow with Checkbox

It should generate a new tab on my second UserControl which I am trying to generate from my ViewModel called HauptfensterViewModel.

Second Window where the Tabs should be generated

The code in the view-model looks like this:

protected void OnWeiterExecute(object obj)
{
    OnDokumentChanged();
    new VorschauViewModel(view);
    if (Dokumenttyp[0] == true)
    {
        //TabItem auf VorschauWindow erstellen, mit jeweiligem Dokumentennamen(Angebotsvorlage)
    }
    if (Dokumenttyp[1] == true)
    {
        //TabItem auf VorschauWindow erstellen mit jeweiligem Dokumentennamen(Auditplan)
    }
    if (Dokumenttyp[2] == true)
    {
        //TabItem auf VorschauWindow erstellen mit jeweiligem Dokumentennamen(Checkliste)
    }
    if (Dokumenttyp[3] == true)
    {
        //TabItem auf VorschauWindow erstellen mit jeweiligem Dokumentennamen(Dokumentationsvorlage)
    }               
}

I appreciate your help and I will try to answer all questions if there is something not understandable.

dymanoid
  • 14,771
  • 4
  • 36
  • 64
kYA
  • 5
  • 4
  • As there are four `CheckBoxes`, so it will add four `TabItems` at most? – Iron Oct 18 '17 at 13:48
  • Are the two `USerControls` in the same `Window`? – Iron Oct 18 '17 at 13:50
  • 3
    Actually, you're totally missing the MVVM concept. A view-model should not create any `TabItem`s (because they're view elements, and a view-model should not bother about any views). This line confirms that fact once again: `new VorschauViewModel(view);` - you're passing a view to a view-model, this is (generally) not MVVM-ish. – dymanoid Oct 18 '17 at 13:51
  • @Iron yes it should generate only 4 TabItems – kYA Oct 18 '17 at 13:52
  • @dymanoid well, ok i didnt know that, thank you.So should i generate them on my UserControl.cs then? – kYA Oct 18 '17 at 13:56
  • No, you shouldn't. You define them in XAML as `DataTemplate`s, or `ControlTemplate`s, or whatever you need, and then you create data bindings for the corresponding view-model properties to let WPF do the job for you. Please read more about MVVM + WPF, these are the basics. – dymanoid Oct 18 '17 at 14:00
  • one approach would be to enable/disable tabs instead of creating and deleting tabs in the control. 2 advantages, one is that it is easy to implement in MVVM and second is that it is faster then creating. – Ehsan Zargar Ershadi Oct 18 '17 at 14:02

1 Answers1

0

May you can try something code like following example, which is not the best solution, but it can help you to understand more about the MVVM.

ViewModel:

public class HauptfensterViewModel : INotifyPropertyChanged
{
    public static HauptfensterViewModel Instance { get; } = new HauptfensterViewModel();

    private HauptfensterViewModel()
    {
    }

    private bool _property1;
    private bool _property2;
    private bool _property3;
    private bool _property4;

    public bool Property1
    {
        get { return _property1; }
        set
        {
            _property1 = value;
            OnPropertyChanged();
        }
    }

    public bool Property2
    {
        get { return _property2; }
        set
        {
            _property2 = value;
            OnPropertyChanged();
        }
    }

    public bool Property3
    {
        get { return _property3; }
        set
        {
            _property3 = value;
            OnPropertyChanged();
        }
    }

    public bool Property4
    {
        get { return _property4; }
        set
        {
            _property4 = value; 
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

UserControl1:

<CheckBox IsChecked="{Binding Property1}"/>
<CheckBox IsChecked="{Binding Property2}"/>
<CheckBox IsChecked="{Binding Property3}"/>
<CheckBox IsChecked="{Binding Property4}"/>

UserControl2:

<TabControl HorizontalAlignment="Right">
    <TabControl.Resources>
        <BooleanToVisibilityConverter x:Key="ToVisibilityConverter"/>
    </TabControl.Resources>
    <TabItem Header="1" Visibility="{Binding Property1,Converter={StaticResource ToVisibilityConverter}}"/>
    <TabItem Header="2" Visibility="{Binding Property2,Converter={StaticResource ToVisibilityConverter}}"/>
    <TabItem Header="3" Visibility="{Binding Property3,Converter={StaticResource ToVisibilityConverter}}"/>
    <TabItem Header="4" Visibility="{Binding Property4,Converter={StaticResource ToVisibilityConverter}}"/>
</TabControl>

Code-behind:

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        DataContext = HauptfensterViewModel.Instance;
    }
}
public partial class UserControl2 : UserControl
{
    public UserControl2()
    {
        DataContext = HauptfensterViewModel.Instance;
    }
}
Iron
  • 926
  • 1
  • 5
  • 16
  • Your solution has three bad design decisions: 1) a `static` property providing a "stateful" object; 2) one view-model for two different views; and 3) wiring a view to a view-model in the view's constructor via a singleton. The code review team would reject such a commit. – dymanoid Oct 18 '17 at 14:15
  • Yes, it not a good solution, just to help a novice to understand more about the `MVVM`. – Iron Oct 18 '17 at 14:21