多参数转换器

Har*_*ola 30 c# silverlight xaml ivalueconverter windows-phone-7

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

提前致谢.

Gon*_*ing 52

转换器始终实现IValueConverter.这意味着对Convert或ConvertBack的调用会传递一个附加参数.该参数是从XAML中提取的.

正如Hitesh Patel建议没有什么可以阻止你在参数中放置多个值,只要你有一个分隔符将它们分开,但你不能使用逗号分隔XAML!

例如

XAML

<TextBlock Text="{Binding Path=ReleaseDate, Mode=OneWay,
                        Converter={StaticResource MyConverter}, 
                        ConverterParameter=Param1|Param2}" />
Run Code Online (Sandbox Code Playgroud)

变流器

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
    }
}
Run Code Online (Sandbox Code Playgroud)

注意,我没有检查它是否管道"|" 字符在XAML中是有效的(应该是),但如果不是只选择另一个不会发生冲突的字符.

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

string[] parameters = parameterString.Split('|');
Run Code Online (Sandbox Code Playgroud)

附录:

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

  • `Regex.Split('QQ')`会在QQ上分崩离析 (2认同)
  • 值得注意的是这个参数不能绑定. (2认同)
  • 值得注意的是,在意大利语中,有一个单词有双 q:“soqquadro” (2认同)

Kam*_*iak 13

您始终可以从DependecyObject类派生,并根据需要添加任意数量的DependencyProperties.例如:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在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}}" />
Run Code Online (Sandbox Code Playgroud)


Inf*_*gic 11

尽管以上答案可能是可行的,但它们似乎过于复杂。只需在XAML代码中使用IMultiValueConverter适当MultiBinding的即可。假设您的ViewModel具有,和属性FirstValue,分别是,a 和a ,则有效的多转换器可能如下所示:SecondValueThirdValueintdoublestring

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.");
  }
}
Run Code Online (Sandbox Code Playgroud)

XAML

<TextBlock.Text>
  <MultiBinding Converter="{StaticResource myNs:MyMultiValueConverter}">
    <Binding Path="FirstValue" />
    <Binding Path="SecondValue" />
    <Binding Path="ThirdValue" />
  </MultiBinding>
</TextBlock.Text>
Run Code Online (Sandbox Code Playgroud)

由于它既不需要弄乱ProvideValue所需的方法MarkupExtension,也不需要DependencyObject 内部(!)转换器的规范,因此,我相信这是最优雅的解决方案。


Alf*_*fie 8

这可以使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

...
Visibility="{Binding Property, 
 Converter={cnv:CustomNullToVisibilityConverter NotNullValue=Visible, NullValue=Collapsed}}" 
/>
...
Run Code Online (Sandbox Code Playgroud)

请务必在中引用转换器的名称空间.xaml。


Jef*_*eff 5

与凯尔·奥尔森的答案类似,您可以使用这样的专业集合:

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>
Run Code Online (Sandbox Code Playgroud)

转换器:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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