代码之家  ›  专栏  ›  技术社区  ›  Catalin DICU

在不使用魔术弦的情况下分离屏幕

  •  6
  • Catalin DICU  · 技术社区  · 15 年前

    我的WPF项目将按如下方式组织:

    Screens
       Group1
          Screen1
             View.xaml
             ViewModel.cs
       Group2
          Screen2
             View.xaml
             ViewModel.cs
    

    展示 Screen1 Screen2 我会用这样的方法: ScreenManager.Show("Group1.Screen1") 这看起来(使用反射)在 Screens.Group1.Screen1 视图和视图模型的命名空间,并实例化它们。

    我怎么能不耦合地消除魔法弦呢 屏幕1 屏幕2 (我不想上课 屏幕2 使用 屏幕1 命名空间)。另外,我还想要某种屏幕发现(自动完成/智能感知)

    或者用某种方法(自动化测试)来验证 ScreenManager.Show 是有效的。

    更新: 我想到了这个:

    public class ScreenNames
    {
        public Group1Screens Group1;
    
        public class Group1Screens
        {
            public ScreenName Screen1;
        }
    }
    
    public sealed class ScreenName
    {
        private ScreenName() { }
    }
    
    public class ScreenManager : IScreenManager
    {
        public void Show(Expression<Func<ScreenNames, ScreenName>> x) {}
    }
    

    用途:

    screenManager.Show(x=>x.Group1.Screen1);
    

    不太理想,但我想违反dry仍然比魔法弦好。我可以自动测试(通过反射)所有调用是否有效。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Mark Seemann    15 年前

    在WPF中不需要所有的ScreenManager内容,因为数据模板引擎可以用纯标记为您处理这些内容。

    您可以使用ContentPresenter和一组数据模板简单地对应用程序的特定区域进行数据绑定。将区域绑定到“根”ViewModel的属性,并让“根”ViewModel实现InotifyPropertiesChanged,以便WPF知道是否更改了该区域中的ViewModel。

    public class RootViewModel : INotifyPropertyChanged
    {
        public object Screen1ViewModel { get; }
    
        public object Screen2ViewModel { get; }
    }
    

    使用将一个ContentPresenter控件绑定到Screen1ViewModel属性

    <ContentControl Content="{Binding Path=Screen1ViewModel}" />
    

    下一个也一样。当需要更改screen1的内容时,只需从代码中重新分配screen1 viewmodel,并且由于引发了propertychanged事件,wpf将提取它并将新的viewmodel绑定到新视图。

    数据模板可以像这样简单:

    <Window.Resources>
        <DataTemplate DataType="{x:Type foo:MyViewModel}">
            <self:MyControl />
        </DataTemplate>
        <DataTemplate DataType="{x:Type foo:MyOtherViewModel}">
            <self:MyOtherControl />
        </DataTemplate>
    </Window.Resources>
    

    如果你不熟悉的话, this article on MVVM in WPF 是一个很好的介绍。

        2
  •  0
  •   Catalin DICU    15 年前

    最后,我使用T4代码生成 ScreenNames 班级。我通过修改这个代码来做到这一点: Auto generate strong typed navigation class for all user controls in ASP.NET web application