2013-05-31 1 views
0

J'ai un ContentControl avec la Content propriété liée à un UserControl dans mon ViewModel, comme je l'ai lu dans cette question: WPF: how do I load user controls dynamically? Cependant lorsque vous essayez de tester cela, mon application ne même pas courir , J'obtiens un message que le concepteur visuel d'interface de XAML de Studion s'est écrasé de manière inattendue, me laissant sans n'importe quelle idée comment et pourquoi ceci se produit.ContentControl pour afficher UserControl plantages VS XAML UI Designer

Aussi, dans mon code, vous remarquerez peut-être que j'utilise un UserControl au lieu de FrameworkElement comme suggéré dans la question mentionnée ci-dessus, j'ai essayé les deux mais ils me donnent tous la même erreur.

EDIT: Après quelques essais, j'ai découvert le problème réside dans cette ligne de code, bien que je ne vois pas pourquoi

private UserControl _currentControl = new TableView(); 

EDIT2: Code ci-dessus Il ne devrait pas être un problen mais parce que TableView est un UserControl, et quand je construis l'application je n'obtiens pas d'erreurs

Comme toujours, toute aide sera grandement appréciée!

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); 
     } 
    } 
... 
+0

La plupart proba bly quelques bogues dans XAML. Assurez-vous que XAML est valide –

+0

@HarisHasan Non, la suppression de la liaison 'Content' dans ma vue et la propriété' UserControl' de mon ViewModel résout le problème. – Kryptoxx

Répondre

1

pls n'appeler votre classe MainViewModel et mettre le code en lui avec UserControl! ce n'est pas la façon MVVM :)

Si vous voulez gérer un type de CurrentWorkspace dans MVVM, alors vous devriez travailler avec Viewmodels et DataTemplates. donc au lieu de définir un usercontrol à CurrentWorkspace - il suffit de définir un viewmodel.

Tout ce dont la propriété ContentControl Content a besoin est un Datatemplate pour savoir comment rendre votre viewmodel.

MainViewModel.cs

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

XAML

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

contrôle du contenu reste le même, mais a besoin d'un DataTemplate pour rendre votre viewmodel

XAML - Ressources

<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> 
+0

Merci beaucoup pour cela, fonctionne parfaitement maintenant! Je suis un novice à toute la scène MVVM, alors s'il vous plaît excusez-moi pour ces erreurs de base. Le seul problème que j'ai maintenant est que je ne peux pas mettre plus de 1 élément dans le contenu de 'Window.Resources', donc je perds mes styles de page. Comment pourrais-je mieux aborder cela? – Kryptoxx

+0

pas de problème.vous pouvez bien sûr mettre le datatemplate dans votre resourcedictionary (voir mon edit) ou vous pouvez créer un nouveau Resourcedictionarys pour tous vos datatemplates et l'ajouter aux MergedDictionaries – blindmeis

+0

Awesome, fonctionne parfaitement bien, et oui peut-être je devrais faire un resourcedictionary pour eux, Juste une autre question, je pourrais être complètement faux mais puisque toutes mes vues sont déclarées dans la classe ViewModelLocator, est-il possible de les récupérer là au lieu de faire une nouvelle instance pour chaque vue dans le MainViewModel? – Kryptoxx