XAML 多参数转换器

jvlzgdj9  于 2023-03-10  发布在  其他
关注(0)|答案(8)|浏览(252)

如何在Windows Phone 7应用程序中使用具有多个参数的转换器?

xkftehaa

xkftehaa1#

转换器总是实现IValueConverter。这意味着对ConvertConvertBack的调用传递单个附加参数。该参数从XAML提取。
正如HiteshPatel所建议的,没有什么可以阻止您将多个值放入参数中,只要您有一个分隔符来分隔它们,但是您不能使用逗号作为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中是有效的(应该是),但如果不是,请选择另一个不冲突的字符。*

对于最简单的Split版本,.Net的更高版本不需要字符数组,因此您可以使用以下字符数组:

string[] parameters = parameterString.Split('|');

附录:

几年前,eBay在URL中使用的一个技巧是用QQ分隔URL中的数据。双Q不会自然出现在文本数据中。如果你遇到了避免编码问题的文本分隔符,就使用QQ......虽然这不适用于分割(需要单个字符,但很高兴知道):)

vc9ivgsu

vc9ivgsu2#

虽然上述答案可能是可行的,但它们似乎过于复杂。只需在XAML代码中将IMultiValueConverter与适当的MultiBinding一起使用。假设ViewModel具有属性FirstValueSecondValueThirdValue,它们分别为intdoublestring,有效的multi转换器可能如下所示:

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>

由于它既不需要摸索MarkupExtension所需的ProvideValue方法,也不需要在 *(!)a转换器中指定DependencyObject *,因此我相信这是最优雅的解决方案。

puruo6ea

puruo6ea3#

您可以从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}}" />
5gfr0r5j

5gfr0r5j4#

这可以通过使用System.Windows.Markup.MarkupExtensiondocs)来完成。
这将允许您向转换器传递值,这些值可以用作参数或返回值,例如:

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中引用转换器的命名空间。

o3imoua4

o3imoua45#

与凯尔Olson的回答类似,您可以使用以下专门的集合:
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;
    }
}

有几种专用集合类型可以满足大多数需要。

olhwl3o2

olhwl3o26#

如果您的输入不适用于字符串,并且您有多个参数(不是绑定),则可以只传递一个集合。定义一个所需类型的集合,以避免某些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;
p5fdfcr1

p5fdfcr17#

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>
wztqucjr

wztqucjr8#

除了Jeff的答案.你还可以传递不同的参数类型.

<Binding.ConverterParameter>
    <x:Array Type="{x:Type sys:Object}">
        <sys:Boolean>true</sys:Boolean>
        <sys:Double>70</sys:Double>
    </x:Array>
</Binding.ConverterParameter>

相关问题