普通の書き方
だいたいConverterの使い方として説明されるのがこんな感じだと思います。
namespace Namespace.Converters { public class CustomConverter: IValueConverter { public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) { // ここに処理を書く throw new NotImplementedException(); } public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) { // ここに処理を書く throw new NotImplementedException(); } } }
Namespaceとかは適当 <Window xmlns:convert="clr-namespace:Namespace.Converters"> <Window.Resources> <convert:CustomConverter x:Key="CustomConverter"/> </Window.Resources> <TextBlock Text="{Binding value, Converter={StaticResource CustomConverter}}"/> </Window>
はい、Resourcesにいちいち入れておくのめんどくさいですね。
直接書く
直接書いてやりましょう。
<Window xmlns:convert="clr-namespace:Namespace.Converters"> <TextBlock> <TextBlock.Text> <Binding Path="value"> <Binding.Converter> <convert:CustomConverter/> </Binding.Converter> </Binding> </TextBlock.Text> </TextBlock> </Window>
XAML長すぎでしょ・・・
Staticインスタンスを作っておく
XAML長すぎ問題がなんとかならないかと探していたところ、”Static作っとけばいいじゃん”みたいな書き込みを見つけました。
public class CustomConverter: IValueConverter { // Staticのインスタンスを作っちゃう private static CustomConverter _instance = new CustomConverter(); public static CustomConverter Instance { get { return _instance; } } public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) { // ここに処理を書く throw new NotImplementedException(); } public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) { // ここに処理を書く throw new NotImplementedException(); } }
呼び出すときはこんな感じ
<Window xmlns:convert="clr-namespace:Namespace.Converters"> <TextBlock Text="{Binding value, Converter={x:Static convert:CustomConverter.Instance}}"/> </Window>
便利になりました。
ただ、Template内で使用するとデザイナーがエラー表示をだします。(VS2013)
(リソースを解決できません みたいなエラー)
コンパイルもできるし、実行も問題ないんですけどね・・・
MarkupExtensionを使う
さらに、MarkupExtension を継承しておけばStaticすらいらなくなります。
public class CustomConverter: MarkupExtension, IValueConverter { public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) { // ここに処理を書く throw new NotImplementedException(); } public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) { // ここに処理を書く throw new NotImplementedException(); } public override object ProvideValue( IServiceProvider serviceProvider ) { return this; } }
<Window xmlns:convert="clr-namespace:Namespace.Converters"> <TextBlock Text="{Binding value, Converter={convert:CustomConverter}}"/> </Window>
😃😃😃😃😃😃😃😃😃
こういうテクニックはなかなか見つからないですね。
参考:
WPF:Converterを使うとき、xamlのResource内で宣言をしたくないときの書き方 - RunningCSharp
WPF: How to use converters without creating static resources