2013-05-07 17 views
13

hat jemand ein Beispiel oder eine Anleitung zur Verwendung von Caliburn Micro zusammen mit ModernUi (https://mui.codeplex.com)?Caliburn Micro und ModernUI Beispiele/Lernprogramme

+1

hilft ich kann mir vorstellen, da ModernUI wie eine Sammlung von Kontrollen sieht, die Sie gerade benötigen würden die Konventionen für jedes Steuerelement in dem Toolkit hinzuzufügen. Der einzige Unterschied wäre, dass CM ChildWindow für die meisten seiner Fensterverwaltung verwendet, und Sie möchten dies wahrscheinlich durch ModernWindow in Ihrer Implementierung ersetzen. Ich denke, dass Sie wahrscheinlich nur Ihre eigene Implementierung für WindowManager (und insbesondere "EnsureWindow" -Methode) http://caliburnmicro.codeplex.com/SourceControl/changeset/view/35582bb2a8dfdd3fcd71a07fa82581ddb93a786f#src/Caliburn.Micro.Silverlight/WindowManager bereitstellen müssen. cs – Charleh

+1

Nun, nach einem Blick scheint es komplexer zu sein.Ich denke, dass die Bereitstellung Ihrer eigenen WindowManager-Implementierung möglicherweise nicht die beste Idee ist, da alle Popups auch die 'ModernWindow'-Klasse implementieren würden. Außerdem sieht es so aus, als würde es Inhalte basierend auf Ressourcen-URLs dynamisch laden, und daher würde ein Viewmodel-First-Ansatz wahrscheinlich nicht funktionieren. – Charleh

Antwort

21

Ok, so hatte ich eine schnelle Durcheinander über mit ihm und einem Blick auf den Mui Foren und dies scheint die beste Lösung zu sein:

Seit dem Fenster lädt Inhalt von URLs, die Sie benötigen einen Blick-First-Ansatz nehmen , und suchen Sie dann die entsprechende VM und binden Sie die beiden.

Der beste Weg, dies zu tun, scheint über die ContentLoader Klasse zu sein, die verwendet wird, um den Inhalt in den ModernWindow zu laden, wenn es angefordert wird. Sie können nur DefaultContentLoader Unterklasse und die notwendige CM Magie liefern geladene Elemente zu verbinden:

public class ModernContentLoader : DefaultContentLoader 
{ 
    protected override object LoadContent(Uri uri) 
    { 
     var content = base.LoadContent(uri); 

     if (content == null) 
      return null; 

     // Locate the right viewmodel for this view 
     var vm = Caliburn.Micro.ViewModelLocator.LocateForView(content); 

     if (vm == null) 
      return content; 

     // Bind it up with CM magic 
     if (content is DependencyObject) 
     { 
      Caliburn.Micro.ViewModelBinder.Bind(vm, content as DependencyObject, null); 
     } 

     return content; 
    } 
} 

Ihr CM Bootstrap-Programm sollte nur ein ModernWindow Viewmodel Bootstrap, die durch eine ModernWindow basierte Sicht gesichert ist (CM versucht EnsureWindow zu verwenden, die eine schafft neue Basis WPF Window-Klasse, es sei denn natürlich Ihre Kontrolle erbt bereits von Window die ModernWindow tut Wenn Sie alle Dialoge und Popups müssen MUI sein, Sie könnten WindowManager neu zu implementieren müssen.):

public class Bootstrapper : Bootstrapper<ModernWindowViewModel> 
{ 
} 

, der einen Leiter (OneActive) und sieht wie folgt sein:

public class ModernWindowViewModel : Conductor<IScreen>.Collection.OneActive 
{ 
} 

Und XAML für die Ansicht ist

ModernWindowView.xaml

<mui:ModernWindow x:Class="WpfApplication4.ViewModels.ModernWindowView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mui="http://firstfloorsoftware.com/ModernUI" 
            Title="ModernWindowView" Height="300" Width="300" ContentLoader="{StaticResource ModernContentLoader}"> 
    <mui:ModernWindow.MenuLinkGroups> 
     <mui:LinkGroupCollection> 
      <mui:LinkGroup GroupName="Hello" DisplayName="Hello"> 
       <mui:LinkGroup.Links> 
        <mui:Link Source="/ViewModels/ChildView.xaml" DisplayName="Click me"></mui:Link> 
       </mui:LinkGroup.Links> 
      </mui:LinkGroup> 
     </mui:LinkGroupCollection> 
    </mui:ModernWindow.MenuLinkGroups> 
</mui:ModernWindow> 

Offensichtlich müssen Sie auch den Loader eine Ressource machen:

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" /> 
      <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.Dark.xaml"/> 
      <ResourceDictionary> 
       <framework:ModernContentLoader x:Key="ModernContentLoader"></framework:ModernContentLoader> 
       <wpfApplication4:Bootstrapper x:Key="Bootstrapper"></wpfApplication4:Bootstrapper> 
      </ResourceDictionary> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

Hier ist die ChildViewModel ich als bin mit Test:

public class ChildViewModel : Conductor<IScreen> 
{ 
    public void ClickMe() 
    { 
     MessageBox.Show("Hello"); 
    } 
} 

Und das XAML für die (nur eine Taste)

<UserControl x:Class="WpfApplication4.ViewModels.ChildView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            Height="350" Width="525"> 
    <Grid> 
     <StackPanel> 
     <TextBlock >Hello World</TextBlock> 
     <Button x:Name="ClickMe" Width="140" Height="50">Hello World</Button> 
     </StackPanel> 
    </Grid> 
</UserControl> 

Und die Proof of Concept:

MUI Example

+0

Großartig, danke! – Matthias

+0

Hey Charleh, danke nochmal für deine Antwort. Es gibt noch ein Problem: Wenn der ViewLocator im ContentLoader nach dem passenden Viewmodel sucht, gibt er immer null zurück und es ist keine Bindung mehr vorhanden. Irgendeine Idee? – Matthias

+0

Charleh, könnten Sie Ihre Arbeitsbeispielquelle irgendwo hochladen? – Matthias

Verwandte Themen