Windows Phone 7アプリケーションで複数のパラメーターを持つコンバーターをどのように使用しますか?
7 に答える
コンバーターは常にIValueConverterを実装します。つまり、ConvertまたはConvertBackを呼び出すと、1つの追加パラメーターが渡されます。そのパラメーターはXAMLから抽出されます。
Hitesh Patelが示唆しているように、後でそれらを区切るための区切り文字がある限り、パラメーターに複数の値を入れるのを止めることはできませんが、XAMLを区切るためにコンマを使用することはできません。
例えば
XAML
<TextBlock Text="{Binding Path=ReleaseDate, Mode=OneWay,
Converter={StaticResource MyConverter},
ConverterParameter=Param1|Param2}" />
コンバータ
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (!string.IsNullOrEmpty(parameterString))
{
string[] parameters = parameterString.Split(new char[]{'|'});
// Now do something with the parameters
}
}
注:パイプ「|」かどうかを確認するためにチェックしていません。文字はXAMLで有効です(あるはずです)が、衝突しない別の文字を選択するだけではありません。
それ以降のバージョンの.Netは、の最も単純なバージョンの文字配列を必要としないため、Split
代わりにこれを使用できます。
string[] parameters = parameterString.Split('|');
補遺:
何年も前にeBayがURLで使用していたトリックは、QQを使用してURL内のデータを区切ることでした。ダブルQは、テキストデータでは自然に発生しません。エンコーディングの問題を回避するテキスト区切り文字で行き詰まった場合は、QQを使用してください...これは分割では機能しません(1文字が必要ですが、知っておくと便利です):)
上記の答えは実行可能かもしれませんが、それらは過度に複雑であるように思われます。XAMLコードでIMultiValueConverter
適切なを使用するだけです。MultiBinding
ViewModelにプロパティ、、、FirstValue
およびSecondValue
があり、それぞれ、、、、およびThirdValue
であるとすると、有効なマルチコンバータは次のようになります。int
double
string
C#
public class MyMultiValueConverter : IMultiValueConverter {
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
int firstValue = (int)values[0];
double secondValue = (double)values[1];
string thirdValue = (string)values[2];
return "You said " + thirdValue + ", but it's rather " + firstValue * secondValue;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException("Going back to what you had isn't supported.");
}
}
XAML
<TextBlock.Text>
<MultiBinding Converter="{StaticResource myNs:MyMultiValueConverter}">
<Binding Path="FirstValue" />
<Binding Path="SecondValue" />
<Binding Path="ThirdValue" />
</MultiBinding>
</TextBlock.Text>
ProvideValue
で必要な方法をいじったり、コンバーターの内部MarkupExtension
(!)を指定したりする必要がないので、これが最も洗練されたソリューションだと思います。DependencyObject
いつでもクラスから派生して、必要な数のオブジェクトをDependecyObject
追加でき ます。DependencyProperty
例えば:
ExampleConverter.cs
public class ExampleConverter : DependencyObject, IValueConverter
{
public string Example
{
get => GetValue(ExampleProperty).ToString();
set => SetValue(ExampleProperty, value);
}
public static readonly DependencyProperty ExampleProperty =
DependencyProperty.Register("Example", typeof(string), typeof(ExampleConverter), new PropertyMetadata(null));
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
//Do the convert
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
そしてXAMLでは:
ExampleView.xaml
<ResourceDictionary>
<converters:ExampleConverter x:Key="ExampleConverter" Example="{Binding YourSecondParam}"/>
</ResourceDictionary>
...
<TextBlock Text="{Binding Path=ReleaseDate, Mode=OneWay,
Converter={StaticResource ExampleConverter},
ConverterParameter={Binding YourFirstParam}}" />
System.Windows.Markup.MarkupExtension
これは、 (docs )を使用して実行できます。
これにより、引数または戻り値として使用できる値をコンバーターに渡すことができます。次に例を示します。
public class CustomNullToVisibilityConverter : MarkupExtension, IValueConverter
{
public object NullValue { get; set; }
public object NotNullValue { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return NullValue;
return NotNullValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
使用法:
...
Visibility="{Binding Property,
Converter={cnv:CustomNullToVisibilityConverter NotNullValue=Visible, NullValue=Collapsed}}"
/>
...
でコンバーターの名前空間を参照してください.xaml
。
カイルオルソンの回答と同様に、次のような特殊コレクションを使用できます。
XAMLファイル:
xmlns:specialized="clr-namespace:System.Collections.Specialized;assembly=System"
<local:BoolToMessage x:Key="BoolToMessage"/>
<Label
>
<Label.Content>
<Binding ElementName="mainWin" Path="HasSeedFile"
FallbackValue="False" Converter="{StaticResource BoolToMessage}"
Mode="OneWay">
<Binding.ConverterParameter>
<specialized:StringCollection>
<sys:String>param1</sys:String>
<sys:String>param2</sys:String>
</specialized:StringCollection>
</Binding.ConverterParameter>
</Binding>
</Label.Content>
</Label>
コンバータ:
using System.Collections.Specialized;
[ValueConversion(typeof(bool), typeof(string))]
public class BoolToMessage : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string[] p = new string[((StringCollection) parameter).Count];
((StringCollection) parameter).CopyTo(p,0);
return (bool) value ? p[0] : p[1];
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
ほとんどのニーズを満たす必要があるいくつかの特殊コレクションタイプがあります。
Xamarinのソリューション:
public class BoolStateConverter : BindableObject, IValueConverter, IMarkupExtension
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var boolValue = (bool)value;
return boolValue ? EnabledValue : DisabledValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
public object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public static BindableProperty EnabledValueProperty = BindableHelper.CreateProperty<string>(nameof(EnabledValue));
public string EnabledValue
{
get => (string)GetValue(EnabledValueProperty);
set => SetValue(EnabledValueProperty, value);
}
public static BindableProperty DisabledValueProperty = BindableHelper.CreateProperty<string>(nameof(DisabledValue));
public string DisabledValue
{
get => (string)GetValue(DisabledValueProperty);
set => SetValue(DisabledValueProperty, value);
}
}
XAML消費:
<ContentPage.Resources>
<ResourceDictionary>
<converters:BoolStateConverter
x:Key="BackwardButtonConverter"
EnabledValue="{x:Static res:Images.IcActiveButton}"
DisabledValue="{x:Static res:Images.IcInactiveButton}" />
</ResourceDictionary>
</ContentPage.Resources>
入力が文字列で機能せず、複数のパラメーター(バインディングではない)がある場合。コレクションを渡すだけです。配列に関するUIエディターの問題を回避するために必要なタイプのいずれかを定義します。
public class BrushCollection : Collection<Brush>
{
}
次に、コレクションを使用してXAMLを追加します
<TextBox.Background >
<Binding Path="HasInitiativeChanged" Converter="{StaticResource changedToBrushConverter}">
<Binding.ConverterParameter>
<local:BrushCollection>
<SolidColorBrush Color="{DynamicResource ThemeTextBackground}"/>
<SolidColorBrush Color="{DynamicResource SecondaryColorBMedium}"/>
</local:BrushCollection>
</Binding.ConverterParameter>
</Binding>
</TextBox.Background>
次に、結果をコンバーターの適切なタイプの配列にキャストします。
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
BrushCollection brushes = (BrushCollection)parameter;