der vollständige Quellcode!
ViewA.xaml
<UserControl x:Class="ModuleA.Views.ViewA" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"> <Grid> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" > <TextBlock Text="{Binding Title}" FontSize="38" /> <Button Command="{Binding UpdateCommand}" Width="100">Update</Button> </StackPanel> </Grid> </UserControl>
ViewA.xaml.cs
using ModuleA.RibbonTabs;
using PrismDemo.Core;
using System.Windows.Controls;
namespace ModuleA.Views
{
[RibbonTab(typeof(ViewATab))]
public partial class ViewA : UserControl, ISupportDataContext
{
public ViewA()
{
InitializeComponent();
}
}
}
ViewB.xaml
<UserControl x:Class="ModuleA.Views.ViewB" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"> <Grid> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" > <TextBlock Text="{Binding Title}" FontSize="38" /> <Button Command="{Binding UpdateCommand}" Width="100">Update</Button> </StackPanel> </Grid> </UserControl>
ViewB.xaml.cs
using ModuleA.RibbonTabs;
using PrismDemo.Core;
using System.Windows.Controls;
namespace ModuleA.Views
{
[RibbonTab(typeof(ViewBTab))]
//the main view can inject any number of tab
//uncomment the following lines and test
//I added the same tab just for demo purposes
//[RibbonTab(typeof(ViewBTab))]
//[RibbonTab(typeof(ViewBTab))]
//[RibbonTab(typeof(ViewBTab))]
public partial class ViewB : UserControl, ISupportDataContext
{
public ViewB()
{
InitializeComponent();
}
}
}
ModuleAModule.cs
using Microsoft.Practices.Unity;
using ModuleA.Views;
using Prism.Modularity;
using Prism.Unity;
namespace ModuleA
{
public class ModuleAModule : IModule
{
IUnityContainer _container;
public ModuleAModule(IUnityContainer container)
{
_container = container;
}
public void Initialize()
{
//register for nav
_container.RegisterTypeForNavigation<ViewA>();
_container.RegisterTypeForNavigation<ViewB>();
}
}
}
RibbonTabAttribute.cs
using System;
namespace PrismDemo.Core
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class RibbonTabAttribute : Attribute
{
public Type Type { get; private set; }
public RibbonTabAttribute(Type ribbonTabType)
{
Type = ribbonTabType;
}
}
}
ISupportDataContext.cs
namespace PrismDemo.Core
{
public interface ISupportDataContext
{
object DataContext { get; set; }
}
}
bootstrapper.cs
using Prism.Unity;
using PrismDemo.Views;
using System.Windows;
using Microsoft.Practices.Unity;
using Prism.Modularity;
using ModuleA;
using Prism.Regions;
using PrismDemo.Prism;
using System.Windows.Controls.Ribbon;
namespace PrismDemo
{
class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<Shell>();
}
protected override void InitializeShell()
{
Application.Current.MainWindow.Show();
}
protected override void ConfigureModuleCatalog()
{
var catalog = (ModuleCatalog)ModuleCatalog;
catalog.AddModule(typeof(ModuleAModule));
}
protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
{
var behaviors = base.ConfigureDefaultRegionBehaviors();
behaviors.AddIfMissing(RibbonRegionBehavior.BehaviorKey, typeof(RibbonRegionBehavior));
return behaviors;
}
}
}
App.xaml
<Application x:Class="PrismDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PrismDemo">
<Application.Resources>
</Application.Resources>
</Application>
App.xaml.cs
using System.Windows;
namespace PrismDemo
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var bs = new Bootstrapper();
bs.Run();
}
}
}
Shell.xaml
<Window x:Class="PrismDemo.Views.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
Title="Shell" Height="720" Width="1280">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Ribbon Grid.Row="0" prism:RegionManager.RegionName="RibbonTabRegion"/>
<DockPanel LastChildFill="True" Grid.Row="1">
<StackPanel>
<Button Content="Navigate ViewA" Command="{Binding NavigateCommand}" CommandParameter="ViewA" />
<Button Content="Navigate ViewB" Command="{Binding NavigateCommand}" CommandParameter="ViewB" />
</StackPanel>
<ContentControl prism:RegionManager.RegionName="ContentRegion" Margin="1,3,3,3" />
</DockPanel>
</Grid>
</Window>
Shell.xaml.cs
namespace PrismDemo.Views
{
public partial class Shell
{
public Shell()
{
InitializeComponent();
}
}
}
ShellViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
namespace PrismDemo.ViewModels
{
public class ShellViewModel : BindableBase
{
IRegionManager _regionManager;
public DelegateCommand<string> NavigateCommand { get; set; }
public ShellViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
NavigateCommand = new DelegateCommand<string>(Navigate);
}
void Navigate(string navigationPath)
{
_regionManager.RequestNavigate("ContentRegion", navigationPath);
}
}
}
RibbonRegionBehavior.cs
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Specialized;
using PrismDemo.Core;
using System.Windows.Controls.Ribbon;
namespace PrismDemo.Prism
{
public class RibbonRegionBehavior : RegionBehavior
{
public const string BehaviorKey = "RibbonRegionBehavior";
public const string RibbonTabRegionName = "RibbonTabRegion";
protected override void OnAttach()
{
if (Region.Name == "ContentRegion")
Region.ActiveViews.CollectionChanged += ActiveViews_CollectionChanged;
}
private void ActiveViews_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
var tabList = new List<RibbonTab>();
foreach (var newView in e.NewItems)
{
foreach (var atr in GetCustomAttributes<RibbonTabAttribute>(newView.GetType()))
{
var ribbonTabItem = Activator.CreateInstance(atr.Type) as RibbonTab;
if (ribbonTabItem is ISupportDataContext && newView is ISupportDataContext)
((ISupportDataContext)ribbonTabItem).DataContext = ((ISupportDataContext)newView).DataContext;
tabList.Add(ribbonTabItem);
}
tabList.ForEach(x => Region.RegionManager.Regions[RibbonTabRegionName].Add(x));
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
var views = Region.RegionManager.Regions[RibbonTabRegionName].Views.ToList();
views.ForEach(x => Region.RegionManager.Regions[RibbonTabRegionName].Remove(x));
}
}
private static IEnumerable<T> GetCustomAttributes<T>(Type type)
{
return type.GetCustomAttributes(typeof(T), true).OfType<T>();
}
}
}
und dies ist die Struktur der Demo-App:
diese Lösung von Brian Lagunas (Prisma owner) versehen wurde sein Pluralsight Kurs (Prism Probleme & Lösungen: Laden Abhängige Ansichten), ** ** Es gibt eine andere Lösung für dieses Problem zur Verfügung gestellt (wieder) durch brian, https://www.youtube.com/watch?v=xH6OgCxdXQc, aber ich denke, die erste Lösung die beste ist und die einfachste
der Blick in den Inhalt Bereich injiziert kann eine beliebige Anzahl von Tabs einspritzt, siehe Kommentar in ViewB. xaml.cs
Warum benötigen Sie das ShellViewModel? Kannst du mehr Informationen geben? – toumir
Mein Hauptbildschirm (Shell.xaml) besteht aus zwei Teilen (i.) Ribbon Tab (Menü anzuzeigen) (ii.) Region-Manager von Prisma vorgesehen also je nach Band Registerkarte geklickt hat, werden Region-Manager sachgemäßen zeigen Views (Usercontrols ...) Angenommen, ich hv zwei Ansichten (i) ViewA -> Zeige Liste (ii.) ViewB -> Zeige Formular Benutzer kann von ViewA zu ViewB gehen durch Bearbeiten Schaltfläche ... Also muss ich den entsprechenden Reiter entsprechend ausgewählt haben ... Also werde ich ShellContext in meinem ViewBViewModel anfordern, damit ich die "IsSelected" -Eigenschaft des Tabs entsprechend setzen kann – user1641519