19. その他
19.1 指示値
オブジェクトをユーザーに表示したいが、それをビューに表示されるカスタム (文字列) ラベルに関連付けたい場合があります。そこで、オブジェクトをラップする単純なクラスを作成し、このタグをアタッチします。
ToString
次に、ビューにラベルのみが表示されるようEquals
にオーバーライドし、(たとえば)GetHashCode
をSelectedItem
持つComboBox
正しく動作するように and をオーバーライドします。INotifyPropertyChanged
最後に、ビューがこれらの変更をキャッチできるように実装する必要があります。
文字列プロパティとプロパティを持つクラスを作成するために必要なのはこれだけLabelledValue<T>
です。オーバーライドされた、、、、および実装もあります。Label
T
Value
ToString
GetHashCode
Equals
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
ほとんどすべてのプロジェクトで、ViewModel のブール値に基づいて要素を非表示/表示する必要があります。これを行うには、DataTriggers またはコンバータを使用できます。
コンバーターの実装は非常に単純です。bool プロパティにバインドされている場合、true 値を読み取ると (事前設定された) 可視性を返し、false 値を読み取ると別の可視性を返します。
bool 以外の型のプロパティにバインドする場合は、次のルールが使用されます。
- 値が null の場合は false として扱います
- 値が 0 (int、float、double など) の場合、false として扱います。
- 値が空のコレクション、辞書などの場合、false として扱います。
- それ以外の場合は true とみなされます
これは、多くの言語の真実/偽ルールに準拠しています。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}}"/>
Visibility.Visible
trueおよび false の場合に使用される通常のコンバーターが必要な場合はVisibility.Collapsed
、ショートカットがあります。
<TextBlock Visibility="{Binding SomeBoolProperty, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"/>
同様に、バインディングでVisibility.Collapsed
astrue
、(これは少し珍しいですが)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 に同様の機能がないのは当然です。私は人々にこの恐ろしいコードを書くことを奨励したくありません。Service Locator パターンは、アンチパターンと呼ばれることがよくあります。現在では、すべてのクラスが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>();
}
}
次に、次のようにブートストラップに配線します。
protected override void Configure()
{
IoC.GetInstance = this.Container.Get;
IoC.GetAllInstances = this.Container.GetAll;
IoC.BuildUp = this.Container.BuildUp;
}
元のプロジェクトのアドレス: https://github.com/canton7/Stylet