IValueConverter - 传递参数,它是我的自定义控件的属性

时间:2016-06-09 16:04:01

标签: c# xaml windows-10-universal

我为自定义控件创建了一个.cs类,它包含以下属性:

  //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));

在同一个班级我定义了单位:

     public enum Units
    {
        Percent,
        Degree,
        Time
    }

现在在generic.xaml文件中,我得到了一个Textblock,该文本绑定到同一个.cs Control类中的另一个 DependencyProperty ,名为Angle - 角度应该显示在正确的格式,因为我使用ValueConverter,它应该返回一个基于Unit属性的值。

我的数据绑定工作正常,但我得到了ValueConverter的问题 - 最后一个参数很重要!

Text="{Binding Mode=TwoWay, ElementName=ringSlice, Path=EndAngle, Converter={StaticResource DoubleDegreesToInt}, ConverterParameter={Binding RelativeSource={RelativeSource TemplatedParent}, Path=Unit}}"

访问ValueConverter类中的参数会抛出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就此而言!

2 个答案:

答案 0 :(得分:3)

无法将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描述了使用Cimbalino Multibinding Behavior的方法。

答案 1 :(得分:2)

我刚刚确认,即使在通用应用中,您仍然无法绑定ConverterParameterref)。如果微软尝试这一点并且它被证明是一个主要的性能瓶颈,我不会感到惊讶。

您可以采取一些解决方法:

  • MultiBinding与您的自定义IMultiValueConverter一起使用(但在UWP应用中可能无法实现这一点?)
  • 创建一个将Units枚举值与数字部分组合在一起的值对象(类似于GridLength
  • MVVM方法

他们各有利弊。如果调用任何绑定项,则调用MultiBinding。如果任何绑定经常更改,则可能需要注意性能问题。注意:要求您走树的绑定非常昂贵。

MVVM方法是让ViewModel具有完全取代IValueConverter的属性。如果Model的Unit和Value属性发生更改,则ViewModel会为计算属性和UI更新引发INotifyPropertyChanged事件。

在容器值对象中,您可以添加XAML帮助程序,以允许您以字符串格式编写快捷方式,并将其自动解析为所需的值对象。我已经使用它对影响放置的属性有很好的效果。绑定仍然是个别领域的问题。

在这种情况下,我会更多地采用MVVM方法 - 即使你在后面的代码中这样做。