WPF MVVM Framework Stylet Development Documentation 19. Miscellaneous

19. Miscellaneous

19.1 Indicated value

document address

Sometimes you want to display an object to the user, but want to associate it with a custom (string) label that will be displayed in your view. So you create a simple class to wrap your object and attach this tag.

Then you'll want to override ToStringso that your view only shows the label, and override Equalsand so that they work correctly GetHashCodewith something that SelectedItemhas (for example). ComboBoxFinally, you need to implement INotifyPropertyChangedso that the view can catch these changes.

That LabelledValue<T>'s all there is to - a class with a string Labelproperty and T Valuea property . There is also an overridden ToString, GetHashCode, Equals, and implementation INotifyPropertyChanged.

For example:

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];
   }
}

So what do you think...

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

19.2 Debug Converter DebugConverter

document address

In every project I need debug bindings. The easiest way to do this is to put a converter on the binding that does nothing but log the values ​​it sees. DebugConverteris an implementation of such a converter that will log every call to Visual Studio's output window as long as you're running a debug build.

Basic usage is very simple:

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

If you want to activate multiple instances at the same time, and want to give each instance a name (to be included in its output), you can do this:

<!-- 在任意.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

document address

In almost every project I need to hide/show elements based on some bool value in ViewModel. You can use DataTriggers or use converters to do this.

The converter implementation is very simple: when bound to a bool property, if it reads a true value, it returns a (preconfigured) visibility, and if it reads a false value, it returns another.

If binding to a property of a type other than bool, it will use the following rules:

  1. If the value is null, treat it as false
  2. If the value is 0 (as int, float, double, etc.), treat it as false
  3. If the value is an empty collection, dictionary, etc., treat it as false
  4. Otherwise, it is considered true

This conforms to the truthsy/falsy rule in many languages. It's also handy if you want to display ListViewif and only if the collection it's bound to is not empty.

Basic example usage:

<!-- 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}}"/>

If you want a usual converter, used when true Visibility.Visibleand false Visibility.Collapsed, there is a shortcut:

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

Likewise, if you want to use Visibility.Collapsedthe as trueand use Visibility.Visiblethe as falsecase (which is slightly unusual), there is a similar shortcut:

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

19.4 IoC: Static Service Locator

document address

Caliburn.Micro comes with a file named IoC. This allows you to access the IoC container from anywhere in your code, like so:

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

It makes sense that Stylet doesn't have a similar feature: I don't want to encourage people to write this horrible code. The Service Locator pattern is often referred to as an anti-pattern. Now every class depends on IoC(rather than the classes it actually depends on), and you can't tell what a class depends on just by looking at its constructor: you have to search your code IoC.Getfor

IoCAlso used to bypass some poorly designed options in Caliburn.Micro . These have been re-architected in Stylet so are no longer needed IoC.

If you really, really need to IoC(and that's a critical issue), you can easily write it yourself. First create this static IoCclass :

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>();
    }
}

Then wire it into your bootstrapper like this:

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

Original project address: https://github.com/canton7/Stylet

Previous: WPF MVVM Framework Stylet Development Document 18. Record Logging

Guess you like

Origin blog.csdn.net/qq_39427511/article/details/130456746