IValueConverter - 传递参数,这是我的自定义控件的 属性
IValueConverter - pass parameter which is a property of my custom control
我为我的自定义控件创建了一个 .cs Class,其中包含以下 属性:
//Property which is defining the unit of the textblock in the Ringslice
public Units Unit
{
get { return (Units)GetValue(UnitProperty); }
set { SetValue(UnitProperty, value); }
}
// Using a DependencyProperty as the backing store for Unit. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UnitProperty =
DependencyProperty.Register("Unit", typeof(Units), typeof(RingPresenter), new PropertyMetadata(Units.Degree));
在同一个class中我定义了单位:
public enum Units
{
Percent,
Degree,
Time
}
现在,在 generic.xaml 文件中,我得到了一个文本块,该文本块绑定到同一 .cs 控件 class 中的另一个 DependencyProperty,称为 Angle
- 角度应该以正确的格式显示,因为我使用的是 ValueConverter,它应该 return 一个基于单位 属性 的值。
我的数据绑定工作正常,但我遇到了 ValueConverter 问题 - 最后一个参数很重要!
Text="{Binding Mode=TwoWay, ElementName=ringSlice, Path=EndAngle, Converter={StaticResource DoubleDegreesToInt}, ConverterParameter={Binding RelativeSource={RelativeSource TemplatedParent}, Path=Unit}}"
访问 ValueConverter 中的参数 class 抛出 NullRefferenceException
- 这是值转换器的代码:
object IValueConverter.Convert(object value, Type targetType, object parameter, string language)
{
Debug.WriteLine(targetType.ToString()); //returning System.String
Debug.WriteLine(parameter.ToString()); //EXCEPTION
return Convert.ToInt32(value); //Is working fine without parameters
}
我做错了什么?我该如何解决这个问题? Ty 敬上!
无法将 ConverterParameter 绑定到 IValueConverter。一种解决方案是使用 here.
中描述的 MultiValueConverter
诀窍是将您的信息打包到一个对象中并像这样绑定属性:
<TextBlock>
<TextBlock.Text>
<MutliBinding Converter="{StaticResource myConverter}">
<MultiBinding.Bindings>
<Binding Path="ABC" />
<Binding Path="DEF" />
</MultiBinding.Bindings>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
您的 MultiValueConverter 使用如下属性:
public class MyConverter: IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (double)values[0] + " " + (double)values[1];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException("Not implemented");
}
}
编辑:
因为在通用 Windows 应用程序中无法进行多重绑定 Damir described a way to use the Cimbalino Multibinding Behavior。
我刚刚确认,即使在 Universal Apps 中,您仍然无法绑定 ConverterParameter
(ref)。如果 Microsoft 尝试这样做并且结果证明这是一个主要的性能瓶颈,我不会感到惊讶。
您可以采取一些解决方法:
- 将
MultiBinding
与您的自定义 IMultiValueConverter
结合使用(但看起来在 UWP 应用程序中可能无法实现?)
- 创建一个将
Units
枚举值与数字部分组合在一起的值对象(有点像 GridLength
)
- MVVM 方法
他们各有利弊。如果调用任何绑定项,则调用 MultiBinding。如果任何绑定经常更改,那么这可能是一个需要注意的性能问题。注意:需要您遍历树的绑定很昂贵。
MVVM 方法是让 ViewModel 属性 完全取代 IValueConverter。如果模型的 Unit 和 Value 属性发生变化,则 ViewModel 会为计算的 属性 和 UI 更新引发 INotifyPropertyChanged 事件。
在容器值对象中,您可以添加XAML 帮助程序,让您可以编写字符串格式的快捷方式,并自动将其解析为您想要的值对象。我已经使用它对影响放置的属性产生了很好的效果。绑定仍然是个别字段的问题。
在这种情况下,我会更多地使用 MVVM 方法——即使您在代码隐藏中进行。
我为我的自定义控件创建了一个 .cs Class,其中包含以下 属性:
//Property which is defining the unit of the textblock in the Ringslice
public Units Unit
{
get { return (Units)GetValue(UnitProperty); }
set { SetValue(UnitProperty, value); }
}
// Using a DependencyProperty as the backing store for Unit. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UnitProperty =
DependencyProperty.Register("Unit", typeof(Units), typeof(RingPresenter), new PropertyMetadata(Units.Degree));
在同一个class中我定义了单位:
public enum Units
{
Percent,
Degree,
Time
}
现在,在 generic.xaml 文件中,我得到了一个文本块,该文本块绑定到同一 .cs 控件 class 中的另一个 DependencyProperty,称为 Angle
- 角度应该以正确的格式显示,因为我使用的是 ValueConverter,它应该 return 一个基于单位 属性 的值。
我的数据绑定工作正常,但我遇到了 ValueConverter 问题 - 最后一个参数很重要!
Text="{Binding Mode=TwoWay, ElementName=ringSlice, Path=EndAngle, Converter={StaticResource DoubleDegreesToInt}, ConverterParameter={Binding RelativeSource={RelativeSource TemplatedParent}, Path=Unit}}"
访问 ValueConverter 中的参数 class 抛出 NullRefferenceException
- 这是值转换器的代码:
object IValueConverter.Convert(object value, Type targetType, object parameter, string language)
{
Debug.WriteLine(targetType.ToString()); //returning System.String
Debug.WriteLine(parameter.ToString()); //EXCEPTION
return Convert.ToInt32(value); //Is working fine without parameters
}
我做错了什么?我该如何解决这个问题? Ty 敬上!
无法将 ConverterParameter 绑定到 IValueConverter。一种解决方案是使用 here.
中描述的 MultiValueConverter诀窍是将您的信息打包到一个对象中并像这样绑定属性:
<TextBlock>
<TextBlock.Text>
<MutliBinding Converter="{StaticResource myConverter}">
<MultiBinding.Bindings>
<Binding Path="ABC" />
<Binding Path="DEF" />
</MultiBinding.Bindings>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
您的 MultiValueConverter 使用如下属性:
public class MyConverter: IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (double)values[0] + " " + (double)values[1];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException("Not implemented");
}
}
编辑:
因为在通用 Windows 应用程序中无法进行多重绑定 Damir described a way to use the Cimbalino Multibinding Behavior。
我刚刚确认,即使在 Universal Apps 中,您仍然无法绑定 ConverterParameter
(ref)。如果 Microsoft 尝试这样做并且结果证明这是一个主要的性能瓶颈,我不会感到惊讶。
您可以采取一些解决方法:
- 将
MultiBinding
与您的自定义IMultiValueConverter
结合使用(但看起来在 UWP 应用程序中可能无法实现?) - 创建一个将
Units
枚举值与数字部分组合在一起的值对象(有点像GridLength
) - MVVM 方法
他们各有利弊。如果调用任何绑定项,则调用 MultiBinding。如果任何绑定经常更改,那么这可能是一个需要注意的性能问题。注意:需要您遍历树的绑定很昂贵。
MVVM 方法是让 ViewModel 属性 完全取代 IValueConverter。如果模型的 Unit 和 Value 属性发生变化,则 ViewModel 会为计算的 属性 和 UI 更新引发 INotifyPropertyChanged 事件。
在容器值对象中,您可以添加XAML 帮助程序,让您可以编写字符串格式的快捷方式,并自动将其解析为您想要的值对象。我已经使用它对影响放置的属性产生了很好的效果。绑定仍然是个别字段的问题。
在这种情况下,我会更多地使用 MVVM 方法——即使您在代码隐藏中进行。