【问题标题】:WPF Multibind converter not returning value?WPF Multibind转换器不返回值?
【发布时间】:2015-05-03 08:11:46
【问题描述】:

我有一个多重绑定调用具有两个绑定的转换器。由于某种原因,它不返回任何东西。我把

<ItemsControl.Width>
    <MultiBinding Converter="{StaticResource ResourceKey=TimelineWidthConverter}">
        <Binding Path="AnimationManager.MaxFrame" ElementName="UC" />
        <Binding Path="AnimationManager.CurrentZoom" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:TimelineAnimationView}}" />
    </MultiBinding>
</ItemsControl.Width>

在 XAML 文件中,转换器读取:

internal class MaterialTimelineWidthConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values == null || values.Length != 2 || ReferenceEquals(values[0], DependencyProperty.UnsetValue) || ReferenceEquals(values[1], DependencyProperty.UnsetValue))
        {
            return 240;
        }

        var maxFrame = System.Convert.ToInt32(values[0]);
        var currentZoom = System.Convert.ToInt32(values[1]);

        return currentZoom*maxFrame;

    }

    public object[] ConvertBack(object values, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

奇怪的是,如果我将 XAML 文件更改为:

<ItemsControl.Width>
    280
</ItemsControl.Width>

它可以工作,但如果我只是在转换器中返回 280,它就不会做任何事情。就好像它什么都不返回,但没有给出任何错误。

转换器以前工作过,当时它只是一个单值转换器(传统绑定,没有多重绑定),但是一旦我添加了第二个属性并将其设为多重,它就不起作用了。有什么建议吗?

【问题讨论】:

  • 您的转换器应该返回一个double 值,而不是int
  • @EliEgseem 我同意@Clemens,问题出在您的转换器类中,同时尝试将double 转换为int。请尝试将值数组项转换为double
  • 您已经在 previous question 的转换器中正确完成了它:-)
  • 是的,它们是两个不同的转换器,但想法是一样的。由于某种原因,另一个崩溃了,但这个没有。感谢您的输入。我会选择一个答案,然后我今晚试一试。

标签: c# wpf xaml converter multibinding


【解决方案1】:

多值转换器返回的值必须与目标属性的类型完全匹配。因此它必须返回一个double 值,而不是int

您还必须正确转换两个输入值。您当前的代码假定 AnimationManager 类的MaxFrameCurrentZoom 属性都是int 类型。如果他们实际上是doubles,请适当更改转换。

public object Convert(
    object[] values, Type targetType, object parameter, CultureInfo culture)
{
    if (values == null || values.Length != 2 ||
        ReferenceEquals(values[0], DependencyProperty.UnsetValue) ||
        ReferenceEquals(values[1], DependencyProperty.UnsetValue))
    {
        return 240d;
    }

    var maxFrame = System.Convert.ToInt32(values[0]); // or ToDouble
    var currentZoom = System.Convert.ToInt32(values[1]); // or ToDouble
    return (double)(currentZoom * maxFrame);
}

一个可能更好的实现可能会检查输入值是否实际上是整数或双精度数(因此也消除了对UnsetValue 的检查):

public object Convert(
    object[] values, Type targetType, object parameter, CultureInfo culture)
{
    double result = 240d;

    if (values != null && values.Length == 2 &&
        values[0] is int && values[1] is int)
    {
        var maxFrame = (int)values[0];
        var currentZoom = (int)values[1];
        result = (double)(currentZoom * maxFrame);
    }

    return result;
}

【讨论】:

  • 很奇怪,它们一开始是双精度数,但在某些时候它们变成了整数。我想如果它不是对无效铸造大惊小怪,那不是那种问题。我会调查并尽快通知您。
  • 啊,我试过了,它有效。这解决了这个问题,但另一个转换器正在使用双打,所以我对这个问题感到困惑。
【解决方案2】:

您正在尝试将 double 转换为 int

...
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{

    if (values == null || values.Length != 2 || values.Any(v => DependencyProperty.UnsetValue.Equals(v)))
        return 240d;

    return values.Cast<double>().Aggregate((v1, v2) => v1 * v2);
}
...

【讨论】:

  • 感谢您的回答,但 Clemens 的解决方案对我来说要简单得多。
  • @AliEgseem 没关系,它们很相似,我用Linq写的;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-15
  • 1970-01-01
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多