截至 2015 年,Prism 是视图注入的唯一选择吗?我在 prism 上读到的很多东西都已经过时了 5 年左右。在我开始学习这个框架之前,我想考虑我所有的选择。就视图注入而言,有什么可以与 Prism 相媲美的吗?
2 回答
首先,您不需要任何框架来进行视图注入。棱镜只是如何做到这一点的一个例子。就个人而言,我喜欢 prism.mvvm,但我会避免使用 prism。这对学习模式和实践很有好处,tought。
我将首先描述另一种称为viewmodel的方法:
它首先被称为视图模型,因为总是首先创建视图模型,然后根据命名约定或任何逻辑选择视图。
我没有将部分视图注入外壳视图,而是将部分视图模型注入外壳视图模型,然后在需要时创建注入视图模型的部分视图。
示例场景:
假设我有带有 tabcontrol 的主窗口,我想注入标签。
在外壳视图模型中,我定义了选项卡集合(它们的视图模型),它将包含注入的选项卡。
public class MainWindowViewModel
{
public MainWindowViewModel()
{
Tabs = new ObservableCollection<ITab>();
}
public ObservableCollection<ITab> Tabs { get; private set; }
}
public interface ITab
{
string Header { get; }
}
在 MainWindow.xaml 中,我使用从 viewmodel 创建视图的转换器显示它们
<TabControl ItemsSource="{Binding Tabs}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Header}" />
</Style>
</TabControl.ItemContainerStyle>
<TabControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Converter={StaticResource ViewModelToViewConverter}}"/>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
ViewModelToViewConverter 的示例可以在这里找到:https ://stackoverflow.com/a/31721236/475727
现在您唯一需要做的就是将选项卡注入到选项卡集合中。例如,将集合传递给您的模块,模块将注入选项卡。
作为注入的替代方法,您可以使用发现。您只需发现所有实现 ITab 接口的类,将它们实例化并添加到 Tabs 集合中。
优点:
- 您不必像使用 prism 中的 RegionManager 那样处理字符串。
- 您可以轻松测试视图模型,包括 shellviewmodel
- 你不依赖于任何框架。
MVVM 灯更...轻,易于使用。对于动态注入,它只是源上的触发器(用于在模型视图中加载对象)和目标控件上的 raiseProperty。
<DataGrid Grid.Column="0" Grid.Row="0" x:Name="dgMain" AutoGenerateColumns="False" SelectionUnit="FullRow" ItemsSource="{Binding Users.items}"
CanUserReorderColumns="True" CanUserResizeColumns="True" CanUserResizeRows="False" CanUserSortColumns="True" CanUserAddRows="False"
LoadingRow="dgMain_LoadingRow" AlternatingRowBackground="#FFEEEEEE" >
<!--DataGrid.DataContext><Binding Source="{StaticResource tblUsers}"/></DataGrid.DataContext-->
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<mvvm:EventToCommand Command="{Binding SendUserCommand, Mode=OneWay}" CommandParameter="{Binding ElementName=dgMain, Path=SelectedItem}"></mvvm:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
就我而言,我使用信使
void SendUserInfo(tblUser obj) {
if (obj != null) {
Messenger.Default.Send<MessageCommunicator>(new MessageCommunicator() { Emp = obj, LeMode=mode.Emp });
}
}
void ReceiveInfo() {
Messenger.Default.Register<MessageCommunicator>(this, (obj) => {
if (obj.LeMode == mode.Emp) {
this.UsrInfo = obj.Emp; // Stocke l'objet.
CloneUser(); // Mémorise pour l'éventuel Undo.
} else if (obj.LeMode == mode.Grp) {
this.GrpInfo = obj.Grp;
CloneGrp();
}
leMode = Mode.Edit;
});
}