有没有人知道如何在Windows Phone 7应用程序中使用带有多个参数的转换器?
先谢谢。
答案 0 :(得分:47)
转换器始终实现IValueConverter。这意味着对Convert或ConvertBack的调用会传递一个附加参数。该参数是从XAML中提取的。
正如Hitesh Patel建议没有什么可以阻止你在参数中放入多个值,只要你有一个分隔符以便稍后将它们分开,但是你不能使用逗号分隔XAML! 强>
e.g。
<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是用QQ分隔网址中的数据。双Q在文本数据中不会自然出现。如果您因为文本分隔符而陷入困境而避免编码问题只需使用QQ ...虽然这不适用于拆分(这需要单个字符,但很高兴知道):)
答案 1 :(得分:10)
您始终可以从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();
}
}
然后在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}}" />
答案 2 :(得分:4)
虽然以上答案可能是可行的,但它们似乎过于复杂。只需在XAML代码中将IMultiValueConverter
与相应的MultiBinding
一起使用即可。假定您的ViewModel具有属性FirstValue
,SecondValue
和ThirdValue
,分别是int
,double
和string
,有效的多转换器分别如下所示:
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.");
}
}
<TextBlock.Text>
<MultiBinding Converter="{StaticResource myNs:MyMultiValueConverter}">
<Binding Path="FirstValue" />
<Binding Path="SecondValue" />
<Binding Path="ThirdValue" />
</MultiBinding>
</TextBlock.Text>
由于它既不需要弄乱ProvideValue
所需的MarkupExtension
方法,也不需要弄清DependencyObject
内部 (!)转换器的规范,我愿意相信这是最优雅的解决方案。
答案 3 :(得分:2)
这可以使用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
中引用转换器的名称空间。
答案 4 :(得分:1)
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>
答案 5 :(得分:1)
类似于凯尔·奥尔森(Kyle Olson)的答案,您可以使用这样的Specialized Collection:
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;
}
}
有几种Specialized Collection类型应该可以满足大多数需求。
答案 6 :(得分:0)
如果您的输入不适用于字符串,并且您具有多个参数(非绑定)。您可以通过收藏集。定义所需的任何一种类型,以避免某些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;