WPF的MVVM框架Stylet开发文档 19. 杂项

19. 杂项

19.1标示值

文档地址

有时候你想要展示一个对象给用户,但是想要为它关联一个自定义的(字符串)标签,这个标签会在你的视图中显示。于是你创建了一个简单的类来包装你的对象,并附加这个标签。

然后你会想要重写 ToString,以便你的视图仅显示标签,并重写 EqualsGetHashCode 以便它们与一些具有 SelectedItem 的东西(例如 ComboBox)正常工作。最后,你需要实现 INotifyPropertyChanged,以便视图能够捕获这些变化。

这就是 LabelledValue<T> 的全部内容 - 一个具有字符串 Label 属性和 T Value 属性的类。还有一个重写的 ToStringGetHashCodeEquals,以及实现 INotifyPropertyChanged

例如:

public enum MyEnum
{
    
    
   Foo,
   Bar,
   Baz
}

class MyViewModel
{
    
    
   // Implement INotifyPropertyChanged if you want
   public BindableCollection<LabelledValue<MyEnum>> EnumValues {
    
     get; private set; }
   public LabelledValue<MyEnum> SelectedEnumValue {
    
     get; set; }

   public MyViewModel()
   {
    
    
      this.EnumValues = new BindableCollection<LabelledValue<MyEnum>>()
      {
    
    
         LabelledValue.Create("Foo Value", MyEnum.Foo),
         LabelledValue.Create("Bar Value", MyEnum.Bar),
         LabelledValue.Create("Baz Value", MyEnum.Baz),
      };

      this.SelectedEnumValue = this.EnumValues[0];
   }
}

那么你的看法…

<ComboBox ItemsSource="{Binding EnumValues}" SelectedItem="{Binding SelectedEnumValue}"/>

19.2 调试转换器DebugConverter

文档地址

在每个项目中,我都需要调试绑定。最简单的方法是在绑定上放置一个转换器,它除了记录其看到的值之外什么也不做。DebugConverter 就是这样的转换器的一个实现,只要您正在运行调试版本,它就会将每个调用记录到 Visual Studio 的输出窗口中。

基本用法非常简单:

<TextBox Text="{Binding MyProperty, Converter={x:Static s:DebugConverter.Instance}}"/>

如果你想同时激活多个实例,并想给每个实例一个名字(包含在它的输出中),你可以这样做:

<!-- 在任意.Resources部分,不一定是Window.Resources -->
<Window.Resources>
   <s:DebugConverter x:key="debugConverter" Name="MySpecialName"/>
</Window.Resources>
<!-- Later in code -->
<TextBlock Text="{Binding MyProperty, Converter={StaticResource debugConverter}}"/>

19.3 BoolToVisibilityConverter

文档地址

扫描二维码关注公众号,回复: 15188863 查看本文章

在几乎每个项目中,我都需要根据 ViewModel 中的某些 bool 值隐藏/显示元素。您可以使用 DataTriggers 或使用转换器来执行此操作。

转换器实现非常简单:当绑定到一个 bool 属性时,如果它读取一个真值,它返回一个(预配置的)可见性,如果它读取一个假值,它返回另一个。

如果绑定到 bool 以外类型的属性,它将使用以下规则:

  1. 如果该值为 null,则将其视为 false
  2. 如果值为 0(作为 int、float、double 等),则将其视为 false
  3. 如果该值为空集合、字典等,则将其视为 false
  4. 否则,它被视为 true

这符合许多语言中的 truthsy/falsy 规则。如果您想要显示ListView当且仅当它绑定到的集合不为空时,它也很方便。

基本示例用法:

<!-- In any .Resources section - doesn't have to be Window.Resources -->
<Window.Resources>
   <s:BoolToVisibilityConverter x:Key="boolToVisConverter" TrueVisibility="Visible" FalseVisibility="Hidden"/>
</Window.Resources>

<!-- Later in code -->
<TextBlock Visibility="{Binding SomeBoolProperty, Converter={StaticResource boolToVisConverter}}"/>

如果你想要一个通常的转换器,true时使用Visibility.Visible,false时使用Visibility.Collapsed,有一个快捷方式:

<TextBlock Visibility="{Binding SomeBoolProperty, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"/>

同样地,如果你想要在绑定中使用 Visibility.Collapsed 作为 true 的情况,而使用 Visibility.Visible 作为 false 的情况(这种情况略有些不寻常),也有一个类似的快捷方式:

<TextBlock Visibility="{Binding SomeBoolProperty, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}}"/>

19.4 IoC:静态服务定位器

文档地址

Caliburn.Micro 带有一个名为IoC. 这使您可以从代码中的任何位置访问 IoC 容器,如下所示:

var vm = IoC.Get<MyDialogViewModel>();
this.windowManager.ShowDialog(vm);

Stylet 没有类似的功能,这也是有道理的:我不想鼓励人们编写这种可怕的代码。服务定位器模式经常被称为反模式。现在每个类都依赖于 IoC(而不是它实际依赖的类),并且你无法仅仅通过查看类的构造函数就知道它的依赖关系:你必须在代码中搜索对 IoC.Get 的调用。

在 Caliburn.Micro 中,IoC 也被用于绕过一些设计不佳的选择。这些已经在 Stylet 中进行了重新架构,因此不再需要 IoC

如果您真的 非常 需要 IoC(这是一个关键问题),那么您可以很容易地自己编写。首先创建这个静态 IoC 类:

public static class IoC
{
    
    
    public static Func<Type, string, object> GetInstance = (service, key) => {
    
     throw new InvalidOperationException("IoC is not initialized"); };

    public static Func<Type, IEnumerable<object>> GetAllInstances = service => {
    
     throw new InvalidOperationException("IoC is not initialized"); };

    public static Action<object> BuildUp = instance => {
    
     throw new InvalidOperationException("IoC is not initialized"); };

    public static T Get<T>(string key = null)
    {
    
    
        return (T)GetInstance(typeof(T), key);
    }

    public static IEnumerable<T> GetAll<T>()
    {
    
    
        return GetAllInstances(typeof(T)).Cast<T>();
    }
}

然后像这样将它连接到你的引导程序(bootstrapper)中:

protected override void Configure()
{
    
    
   IoC.GetInstance = this.Container.Get;
   IoC.GetAllInstances = this.Container.GetAll;
   IoC.BuildUp = this.Container.BuildUp;
}

项目原地址:https://github.com/canton7/Stylet

上一篇:WPF的MVVM框架Stylet开发文档 18.记录 Logging

猜你喜欢

转载自blog.csdn.net/qq_39427511/article/details/130456746