0

I have a ContentControl with the Content property bound to a UserControl in my ViewModel, like I read in this question: WPF: how do I load user controls dynamically? However when trying to test this, my app doesn't even run, I get a message that the Visual Studion XAML UI Designer has crashed unexpectedly, leaving me without any clue how and why this is happening.

Also, in my code you may notice I use a UserControl instead of FrameworkElement as suggested in the above mentioned question, I tried both but they each give me the same error.

EDIT: After some testing, I found out the problem lies in this line of code, although I don't see why

    private UserControl _currentControl = new TableView();

EDIT2: There code above shouldn't be a problen though because TableView is a UserControl, and when I build the application I get no errors

As always, any help will be greatly appreciated!

MainWindow.xaml

<Fluent:RibbonWindow x:Class="DatabaseExplorer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:Fluent="clr-namespace:Fluent;assembly=Fluent"
        xmlns:View="clr-namespace:DatabaseExplorer.Views"
        xmlns:ignore="http://www.ignore.com"
        mc:Ignorable="d ignore"
        Height="300"
        Width="300"
        Title="Application"
        DataContext="{Binding Main, Source={StaticResource Locator}}">

    <Fluent:RibbonWindow.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Skins/MainSkin.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Fluent:RibbonWindow.Resources>

    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Fluent:Ribbon>
            ...
        </Fluent:Ribbon>
        <ContentControl Grid.Row="1"  Content="{Binding CurrentControl}" />
    </Grid>
</Fluent:RibbonWindow>

MainViewModel.cs

...
    /// <summary>
    /// The <see cref="CurrentControl" /> property's name.
    /// </summary>
    public const string CurrentControlPropertyName = "CurrentControl";

    private UserControl _currentControl = new TableView();

    /// <summary>
    /// Sets and gets the CurrentControl property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public UserControl CurrentControl
    {
        get
        {
            return _currentControl;
        }

        set
        {
            if (_currentControl == value)
            {
                return;
            }

            RaisePropertyChanging(CurrentControlPropertyName);
            _currentControl = value;
            RaisePropertyChanged(CurrentControlPropertyName);
        }
    }
...
Community
  • 1
  • 1
Kryptoxx
  • 561
  • 4
  • 22

1 Answers1

1

pls dont call your class MainViewModel and put code in it with UserControl! thats not the MVVM way :)

if you wanna handle some kind of CurrentWorkspace in MVVM then you should work with Viewmodels and DataTemplates. so instead to set a usercontrol to the CurrentWorkspace - simply set a viewmodel.

all the ContentControl Content property needs is a Datatemplate to know how to render your viewmodel.

MainViewModel.cs

 public object CurrentWorkspace {get;set;}
 ...
 this.CurrentWorkspace = this._myViewmodelInstanceWithSomeCoolThings;

xaml

<ContentControl Grid.Row="1"  Content="{Binding CurrentWorkspace }" />

content control stays the same, but needs a datatemplate to render your viewmodel

xaml - resources

 <Fluent:RibbonWindow.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Skins/MainSkin.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <DataTemplate DataType="{x:Type local:ViewModelWithSomeCoolthingsClass}">
          <local:MyViewForViewModelWithSomeCoolthingsClass />
        </DataTemplate>
    </ResourceDictionary>      
 </Fluent:RibbonWindow.Resources>
blindmeis
  • 22,175
  • 7
  • 55
  • 74
  • Thank you so much for this, works perfectly now! I'm a newbie to the whole MVVM scene, so please excuse me for such basic mistakes. The only problem I have now is that I can't put more than 1 element in the `Window.Resources` content, so I lose my page styles. How would I best approach this? – Kryptoxx May 31 '13 at 10:24
  • no problem. you can of course put the datatemplate in your resourcedictionary (see my edit) or you can create a new Resourcedictionarys for all your datatemplates and add it to the MergedDictionaries – blindmeis May 31 '13 at 10:39
  • Awesome, works perfectly fine, and yeah maybe I should make a resourcedictionary for them, seems appropriate ;) Just one more question, I might be completly wrong but since all my views are declared in the ViewModelLocator class, is it possible to retrieve them there instead of making a new instance for each view in the MainViewModel? – Kryptoxx May 31 '13 at 10:45
  • i dont know mvvm-light so you better ask a new question with some code. i dont use any kind of viewmodellocator in my projects – blindmeis May 31 '13 at 11:00
  • Okay no problem, many thanks for all the other help though, you're a lifesaver! :) – Kryptoxx May 31 '13 at 11:04