我目前正在與Prism 6 WPF應用程序工作...我有ShellViewModel,ViewAViewModel和ViewBViewModel。棱鏡6獲取ShellViewModel上下文內其他視圖模型
在Shell.xaml中,我定義了「mainRegion」。當應用程序啓動時,默認情況下在該區域顯示ViewA。
現在,當我從ViewA到VIEWB,在這一點(內部ViewBViewModel),我需要有ShellViewModel的上下文。
任何建議,以實現這一目標?
我目前正在與Prism 6 WPF應用程序工作...我有ShellViewModel,ViewAViewModel和ViewBViewModel。棱鏡6獲取ShellViewModel上下文內其他視圖模型
在Shell.xaml中,我定義了「mainRegion」。當應用程序啓動時,默認情況下在該區域顯示ViewA。
現在,當我從ViewA到VIEWB,在這一點(內部ViewBViewModel),我需要有ShellViewModel的上下文。
任何建議,以實現這一目標?
完整的源代碼!
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>();
}
}
}
該溶液由Brian拉古納斯(棱鏡所有者)中提供他的Pluralsight課程(棱鏡問題&解決方案:加載從屬視圖),** **還有另一個解決方案由Brian,https://www.youtube.com/watch?v=xH6OgCxdXQc(再次)提供了這個問題,但我認爲第一個解決方案是最好的,最簡單的
在內容區域注入可注入任何數目的標籤看,看到評論中ViewB。 xaml.cs
感謝您的評論! 你能在壓縮文件中分享上面的工作代碼嗎?因爲我沒有多個視線帳戶和上面的代碼給出一些錯誤。 – user1641519
該解決方案完美地工作,這是下載演示項目的鏈接:https://onedrive.live.com/redir?resid=576726C17319C174!1229&authkey=!AE9MO4QC77LR7jM&ithint=file%2czip – toumir
偉人:)非常感謝! 。我會檢查解決方案。 – user1641519
爲什麼你需要ShellViewModel?你能提供更多的信息嗎? – toumir
我的主屏幕(Shell.xaml)由兩個部分組成 (我)碳帶標籤(顯示菜單) (二)大區經理通過棱鏡 因此,根據功能區選項卡上單擊,區域管理器將顯示appropiate提供(i)ViewA - >顯示列表 (ii。)ViewB - >顯示錶格 假設我有兩個視圖 (i)ViewA→顯示列表 用戶可以通過編輯按鈕從ViewA到ViewB ...所以我需要顯示相應的選項卡相應地... 所以將在我的ViewBViewModel中請求ShellContext,以便我可以相應地設置選項卡的「IsSelected」屬性 – user1641519