wpf
バリューおよびマルチバリューコンバータ
サーチ…
パラメーター
パラメータ | 詳細 |
---|---|
値 | バインディングソースによって生成される値。 |
値 | バインディングソースによって生成されるvalues配列。 |
targetType | バインディングターゲットプロパティの型。 |
パラメータ | 使用するコンバータパラメータ。 |
文化 | コンバーターで使用する文化。 |
備考
IValueConverterとIMultiValueConverterは何ですか?
IValueConverterとIMultiValueConverter - バインディングにカスタムロジックを適用する方法を提供するインターフェイス。
彼らは何のために便利です
- いくつかの型の値がありますが、一方向にゼロの値を、別の方法で正の数を表示したい
- あるタイプの値を持ち、あるケースに要素を表示し、別のケースで非表示にしたい
- あなたは数値の数値を持っていますが、それを単語として表示したい
- あなたは数値を持っていますが、異なる数の画像を表示したい
これらは単純なケースのいくつかですが、さらに多くのケースがあります。
このような場合は、値コンバーターを使用できます。 IValueConverterインターフェイスまたはIMultiValueConverterを実装するこれらの小さなクラスは、中間者のように動作し、ソースとデスティネーションの間の値を変換します。したがって、値が変換先に到達する前に変換する必要がある場合や変換元に戻す必要がある場合は、コンバータが必要になる可能性があります。
ビルドインBooleanToVisibilityConverter [IValueConverter]
ブール値と可視性の間のコンバータ。入力時にbool
値を取得し、 Visibility
値を返します。
注:このコンバータは既にSystem.Windows.Controls
名前空間に存在します。
public sealed class BooleanToVisibilityConverter : IValueConverter
{
/// <summary>
/// Convert bool or Nullable bool to Visibility
/// </summary>
/// <param name="value">bool or Nullable bool</param>
/// <param name="targetType">Visibility</param>
/// <param name="parameter">null</param>
/// <param name="culture">null</param>
/// <returns>Visible or Collapsed</returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool bValue = false;
if (value is bool)
{
bValue = (bool)value;
}
else if (value is Nullable<bool>)
{
Nullable<bool> tmp = (Nullable<bool>)value;
bValue = tmp.HasValue ? tmp.Value : false;
}
return (bValue) ? Visibility.Visible : Visibility.Collapsed;
}
/// <summary>
/// Convert Visibility to boolean
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Visibility)
{
return (Visibility)value == Visibility.Visible;
}
else
{
return false;
}
}
}
コンバータの使用
- リソースを定義する
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
- バインディングで使用する
<Button Visibility="{Binding AllowEditing,
Converter={StaticResource BooleanToVisibilityConverter}}"/>
プロパティを持つコンバータ[IValueConverter]
プロパティを使用してパラメータを持つ単純なコンバータを作成し、それを宣言で渡す方法を示します。 bool
値をVisibility
変換します。 Inverted
プロパティをTrue
設定すると、結果の値を反転させることができます。
public class BooleanToVisibilityConverter : IValueConverter
{
public bool Inverted { get; set; }
/// <summary>
/// Convert bool or Nullable bool to Visibility
/// </summary>
/// <param name="value">bool or Nullable bool</param>
/// <param name="targetType">Visibility</param>
/// <param name="parameter">null</param>
/// <param name="culture">null</param>
/// <returns>Visible or Collapsed</returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool bValue = false;
if (value is bool)
{
bValue = (bool)value;
}
else if (value is Nullable<bool>)
{
Nullable<bool> tmp = (Nullable<bool>)value;
bValue = tmp ?? false;
}
if (Inverted)
bValue = !bValue;
return (bValue) ? Visibility.Visible : Visibility.Collapsed;
}
/// <summary>
/// Convert Visibility to boolean
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns>True or False</returns>
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Visibility)
{
return ((Visibility) value == Visibility.Visible) && !Inverted;
}
return false;
}
}
コンバータの使用
- 名前空間を定義する
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
- リソースを定義する
<converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityInvertedConverter"
Inverted="False"/>
- バインディングで使用する
<Button Visibility="{Binding AllowEditing, Converter={StaticResource BoolToVisibilityConverter}}"/>
シンプルな追加コンバータ[IMultiValueConverter]
単純なIMultiValueConverter
コンバータを作成し、 IMultiValueConverter
を使用するMultiBinding
を示します。 values
arrayによって渡されたすべての値の合計を取得しvalues
。
public class AddConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
decimal sum = 0M;
foreach (string value in values)
{
decimal parseResult;
if (decimal.TryParse(value, out parseResult))
{
sum += parseResult;
}
}
return sum.ToString(culture);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
コンバータの使用
- 名前空間を定義する
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
- リソースを定義する
<converters:AddConverter x:Key="AddConverter"/>
- バインディングで使用する
<StackPanel Orientation="Vertical">
<TextBox x:Name="TextBox" />
<TextBox x:Name="TextBox1" />
<TextBlock >
<TextBlock.Text>
<MultiBinding Converter="{StaticResource AddConverter}">
<Binding Path="Text" ElementName="TextBox"/>
<Binding Path="Text" ElementName="TextBox1"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
ConverterParameterを使用するコンバーター
単純なコンバータを作成し、 ConverterParameter
を使用してConverterParameter
にパラメータを渡す方法を示します。 ConverterParameterで渡された係数で値を掛けます。
public class MultiplyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return 0;
if (parameter == null)
parameter = 1;
double number;
double coefficient;
if (double.TryParse(value.ToString(), out number) && double.TryParse(parameter.ToString(), out coefficient))
{
return number * coefficient;
}
return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
コンバータの使用
- 名前空間を定義する
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
- リソースを定義する
<converters:MultiplyConverter x:Key="MultiplyConverter"/>
- バインディングで使用する
<StackPanel Orientation="Vertical">
<TextBox x:Name="TextBox" />
<TextBlock Text="{Binding Path=Text,
ElementName=TextBox,
Converter={StaticResource MultiplyConverter},
ConverterParameter=10}"/>
</StackPanel>
複数のコンバータをグループ化する[IValueConverter]
このコンバータは、複数のコンバータを連鎖させます。
public class ValueConverterGroup : List<IValueConverter>, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return this.Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
この例では、ブールからの結果EnumToBooleanConverter
、入力として使用されるBooleanToVisibilityConverter
。
<local:ValueConverterGroup x:Key="EnumToVisibilityConverter">
<local:EnumToBooleanConverter/>
<local:BooleanToVisibilityConverter/>
</local:ValueConverterGroup>
このボタンは、 CurrentMode
プロパティがReady
設定されている場合にのみ表示されます。
<Button Content="Ok" Visibility="{Binding Path=CurrentMode, Converter={StaticResource EnumToVisibilityConverter}, ConverterParameter={x:Static local:Mode.Ready}"/>
コンバーターでMarkupExtensionを使用してソースコード宣言をスキップする
通常、コンバータを使用するには、コンバータを次のようにリソースとして定義する必要があります。
<converters:SomeConverter x:Key="SomeConverter"/>
このステップをスキップするには、コンバータをMarkupExtension
として定義し、メソッドProvideValue
を実装します。次の例では、値を負の値に変換します。
namespace MyProject.Converters
{
public class Converter_Negative : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return this.ReturnNegative(value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return this.ReturnNegative(value);
}
private object ReturnNegative(object value)
{
object result = null;
var @switch = new Dictionary<Type, Action> {
{ typeof(bool), () => result=!(bool)value },
{ typeof(byte), () => result=-1*(byte)value },
{ typeof(short), () => result=-1*(short)value },
{ typeof(int), () => result=-1*(int)value },
{ typeof(long), () => result=-1*(long)value },
{ typeof(float), () => result=-1f*(float)value },
{ typeof(double), () => result=-1d*(double)value },
{ typeof(decimal), () => result=-1m*(decimal)value }
};
@switch[value.GetType()]();
if (result == null) throw new NotImplementedException();
return result;
}
public Converter_Negative()
: base()
{
}
private static Converter_Negative _converter = null;
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (_converter == null) _converter = new Converter_Negative();
return _converter;
}
}
}
コンバータを使用する:
名前空間を定義する
xmlns:converters = "clr-namespace:MyProject.Converters; assembly = MyProject"
バインディングでのこのコンバータの使用例
<RichTextBox IsReadOnly="{Binding Path=IsChecked, ElementName=toggleIsEnabled, Converter={converters:Converter_Negative}}"/>
IMultiValueConverterを使用して複数のパラメータをコマンドに渡す
非常に単純なIMultiValueConverter
を使用して、 MultiBinding
を使用して複数のバインドされた値をCommandParameter
として渡すことができます。
namespace MyProject.Converters
{
public class Converter_MultipleCommandParameters : MarkupExtension, IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values.ToArray();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
private static Converter_MultipleCommandParameters _converter = null;
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (_converter == null) _converter = new Converter_MultipleCommandParameters();
return _converter;
}
public Converter_MultipleCommandParameters()
: base()
{
}
}
}
コンバータを使用する:
実装例 -
SomeCommand
が実行されたときに呼び出されるSomeCommand
です( 注:DelegateCommand
はこの例では提供されていないICommand
実装です )。private ICommand _SomeCommand; public ICommand SomeCommand { get { return _SomeCommand ?? (_SomeCommand = new DelegateCommand(a => OnSomeCommand(a))); } } private void OnSomeCommand(object item) { object[] parameters = item as object[]; MessageBox.Show( string.Format("Execute command: {0}\nParameter 1: {1}\nParamter 2: {2}\nParamter 3: {3}", "SomeCommand", parameters[0], parameters[1], parameters[2])); }
名前空間を定義する
xmlns:converters = "clr-namespace:MyProject.Converters; assembly = MyProject"
バインディングでのこのコンバータの使用例
<Button Width="150" Height="23" Content="Execute some command" Name="btnTestSomeCommand" Command="{Binding Path=SomeCommand}" > <Button.CommandParameter> <MultiBinding Converter="{converters:Converter_MultipleCommandParameters}"> <Binding RelativeSource="{RelativeSource Self}" Path="IsFocused"/> <Binding RelativeSource="{RelativeSource Self}" Path="Name"/> <Binding RelativeSource="{RelativeSource Self}" Path="ActualWidth"/> </MultiBinding> </Button.CommandParameter> </Button>