آموزش Prism #2
نویسنده: مسعود پاکدل
تاریخ: ۱۳۹۲/۰۴/۰۳ ۹:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
<Window x:Class="FirstPrismSample.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:com="http://www.codeplex.com/CompositeWPF"
Title="Prism Sample By Masoud Pakdel" Height="400" Width="600" WindowStartupLocation="CenterScreen">
<DockPanel>
<ContentControl com:RegionManager.RegionName="WorkspaceRegion" Width="400"/>
<ContentControl com:RegionManager.RegionName="NavigatorRegion" DockPanel.Dock="Left" Width="200" />
</DockPanel>
</Window>کد کلاس ViewModelBase که فقط اینترفیس INotifyPropertyChanged رو پیاده سازی کرده است:
using System.ComponentModel;
namespace FirstPrismSample.Common
{
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent( string propertyName )
{
if ( PropertyChanged != null )
{
PropertyChangedEventArgs e = new PropertyChangedEventArgs( propertyName );
PropertyChanged( this, e );
}
}
}
}using Microsoft.Practices.Composite.Presentation.Events;
namespace FirstPrismSample.Common.Events
{
public class ViewRequestedEvent : CompositePresentationEvent<string>
{
}
}namespace FirstPrismSample .Common
{
public interface IModuleServices
{
void ActivateView(string viewName);
}
}using Microsoft.Practices.Composite.Regions;
using Microsoft.Practices.Unity;
namespace FirstPrismSample.Common
{
public class ModuleServices : IModuleServices
{
private readonly IUnityContainer m_Container;
public ModuleServices(IUnityContainer container)
{
m_Container = container;
}
public void ActivateView(string viewName)
{
var regionManager = m_Container.Resolve<IRegionManager>();
// غیر فعال کردن ویو
IRegion workspaceRegion = regionManager.Regions["WorkspaceRegion"];
var views = workspaceRegion.Views;
foreach (var view in views)
{
workspaceRegion.Deactivate(view);
}
//فعال کردن ویو انتخاب شده
var viewToActivate = regionManager.Regions["WorkspaceRegion"].GetView(viewName);
regionManager.Regions["WorkspaceRegion"].Activate(viewToActivate);
}
}
}<UserControl x:Class="FirstPrismSample.ModuleCategory.CategoryView "
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="LightGray" FlowDirection="RightToLeft" FontFamily="Tahoma">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text=" طبقه بندی ها"/>
<ListView Grid.Row="1" Margin="10" Name="lvCategory">
<ListView.View>
<GridView>
<GridViewColumn Header="کد" Width="50" />
<GridViewColumn Header="عنوان" Width="200" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</UserControl>using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.Regions;
using Microsoft.Practices.Unity;
using FirstPrismSample.Common;
using FirstPrismSample.Common.Events;
using Microsoft.Practices.Composite.Presentation.Events;
namespace FirstPrismSample.ModuleCategory
{
[Module(ModuleName = "ModuleCategory")]
public class CategoryModule : IModule
{
private readonly IUnityContainer m_Container;
private readonly string moduleName = "ModuleCategory";
public CategoryModule(IUnityContainer container)
{
m_Container = container;
}
~CategoryModule()
{
var eventAggregator = m_Container.Resolve<IEventAggregator>();
var viewRequestedEvent = eventAggregator.GetEvent<ViewRequestedEvent>();
viewRequestedEvent.Unsubscribe(ViewRequestedEventHandler);
}
public void Initialize()
{
var regionManager = m_Container.Resolve<IRegionManager>();
regionManager.Regions["WorkspaceRegion"].Add(new CategoryView(), moduleName);
var eventAggregator = m_Container.Resolve<IEventAggregator>();
var viewRequestedEvent = eventAggregator.GetEvent<ViewRequestedEvent>();
viewRequestedEvent.Subscribe(this.ViewRequestedEventHandler, true);
}
public void ViewRequestedEventHandler(string moduleName)
{
if (this.moduleName != moduleName) return;
var moduleServices = m_Container.Resolve<IModuleServices>();
moduleServices.ActivateView(moduleName);
}
}
}*برای تعریف ماژول کلاس مورد نظر حتما باید اینترفیس IModule را پیاده سازی کند. این اینترفیس فقط شامل یک متد است به نام Initialize.
*در این پروژه چون Viewهای برنامه صرفا جهت نمایش هستند در نتیجه نیاز به ایجاد ViewModel برای آنها نیست. در پروژههای اجرایی حتما برای هر View باید ViewModel متناظر با آن تهیه شود.
توضیح درباره متد Initialize
در این متد ابتدا با استفاده از Container موجود RegionManager را به دست میآوریم. با استفاده از RegionManager میتونیم یک CompositeUI طراحی کنیم. در فایل Shell مشاهده کردید که یک صفحه به دو ناحیه تقسیم شد و به هر ناحیه هم یک نام اختصاص دادیم. دستور زیر به یک ناحیه اشاره خواهد داشت:
regionManager.Regions["WorkspaceRegion"]
<UserControl x:Class="FirstPrismSample.ModuleBook.BookView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="LightGray" FontFamily="Tahoma" FlowDirection="RightToLeft">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="لیست کتاب ها"/>
<ListView Grid.Row="1" Margin="10" Name="lvBook">
<ListView.View>
<GridView>
<GridViewColumn Header="کد" Width="50" />
<GridViewColumn Header="عنوان" Width="200" />
<GridViewColumn Header="نویسنده" Width="150" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</UserControl>using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.Presentation.Events;
using Microsoft.Practices.Composite.Regions;
using Microsoft.Practices.Unity;
using FirstPrismSample.Common;
using FirstPrismSample.Common.Events;
namespace FirstPrismSample.ModuleBook
{
[Module(ModuleName = "moduleBook")]
public class BookModule : IModule
{
private readonly IUnityContainer m_Container;
private readonly string moduleName = "ModuleBook";
public BookModule(IUnityContainer container)
{
m_Container = container;
}
~BookModule()
{
var eventAggregator = m_Container.Resolve<IEventAggregator>();
var viewRequestedEvent = eventAggregator.GetEvent<ViewRequestedEvent>();
viewRequestedEvent.Unsubscribe(ViewRequestedEventHandler);
}
public void Initialize()
{
var regionManager = m_Container.Resolve<IRegionManager>();
var view = new BookView();
regionManager.Regions["WorkspaceRegion"].Add(view, moduleName);
regionManager.Regions["WorkspaceRegion"].Deactivate(view);
var eventAggregator = m_Container.Resolve<IEventAggregator>();
var viewRequestedEvent = eventAggregator.GetEvent<ViewRequestedEvent>();
viewRequestedEvent.Subscribe(this.ViewRequestedEventHandler, true);
}
public void ViewRequestedEventHandler(string moduleName)
{
if (this.moduleName != moduleName) return;
var moduleServices = m_Container.Resolve<IModuleServices>();
moduleServices.ActivateView(m_WorkspaceBName);
}
}
}<UserControl x:Class="FirstPrismSample.ModuleNavigator.NavigatorView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Grid>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="انتخاب ماژول" Foreground="Green" HorizontalAlignment="Center"
VerticalAlignment="Center" FontFamily="Tahoma" FontSize="24" FontWeight="Bold" />
<Button Command="{Binding ShowModuleCategory}" Margin="5" Width="125">طبقه بندی کتاب ها</Button>
<Button Command="{Binding ShowModuleBook}" Margin="5" Width="125">لیست کتاب ها</Button>
</StackPanel>
</Grid>
</UserControl>public interface INavigatorViewModel
{
ICommand ShowModuleCategory { get; set; }
ICommand ShowModuleBook { get; set; }
string ActiveWorkspace { get; set; }
IUnityContainer Container { get; set; }
event PropertyChangedEventHandler PropertyChanged;
}public class NavigatorViewModel : ViewModelBase, INavigatorViewModel
{
public NavigatorViewModel(IUnityContainer container)
{
this.Initialize(container);
}
public ICommand ShowModuleCategory { get; set; }
public ICommand ShowModuleBook { get; set; }
public string ActiveWorkspace { get; set; }
public IUnityContainer Container { get; set; }
private void Initialize(IUnityContainer container)
{
this.Container = container;
this.ShowModuleCategory = new ShowModuleCategoryCommand(this);
this.ShowModuleBook = new ShowModuleBookCommand(this);
this.ActiveWorkspace = "ModuleCategory";
}
}public class ShowModuleCategoryCommand : ICommand
{
private readonly NavigatorViewModel viewModel;
private const string workspaceName = "ModuleCategory";
public ShowModuleCategoryCommand(NavigatorViewModel viewModel)
{
this.viewModel = viewModel;
}
public bool CanExecute(object parameter)
{
return viewModel.ActiveWorkspace != workspaceName;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
CommandServices.ShowWorkspace(workspaceName, viewModel);
}
}public class ShowModuleBookCommand : ICommand
{
private readonly NavigatorViewModel viewModel;
private readonly string workspaceName = "ModuleBook";
public ShowModuleBookCommand( NavigatorViewModel viewModel )
{
this.viewModel = viewModel;
}
public bool CanExecute( object parameter )
{
return viewModel.ActiveWorkspace != workspaceName;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute( object parameter )
{
CommandServices.ShowWorkspace( workspaceName , viewModel );
}
}public static void ShowWorkspace(string workspaceName, INavigatorViewModel viewModel)
{
var eventAggregator = viewModel.Container.Resolve<IEventAggregator>();
var viewRequestedEvent = eventAggregator.GetEvent<ViewRequestedEvent>();
viewRequestedEvent.Publish(workspaceName);
viewModel.ActiveWorkspace = workspaceName;
}xcopy "$(TargetDir)FirstPrismSample.ModuleBook.dll" "$(SolutionDir)FirstPrismSample\bin\$(ConfigurationName)\Modules\" /Y
public class Bootstrapper : UnityBootstrapper
{
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<IModuleServices, ModuleServices>();
}
protected override DependencyObject CreateShell()
{
var shell = new Shell();
shell.Show();
return shell;
}
protected override IModuleCatalog GetModuleCatalog()
{
var catalog = new DirectoryModuleCatalog();
catalog.ModulePath = @".\Modules";
return catalog;
}
}"$(SolutionDir)FirstPrismSample\bin\$(ConfigurationName)\Modules\" /Y
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var bootstrapper = new Bootstrapper();
bootstrapper.Run();
}
}PM> Install-Package Prism.StructureMapExtensions
xcopy "$(SolutionDir)\PrismProject.ModuleBook\bin\$(ConfigurationName)\PrismProject.ModuleBook.dll" "$(SolutionDir)PrismProject\bin\$(ConfigurationName)\Modules\" /Y