4

在我正在排除故障的遗留组件中,我偶然发现了以下内容:

<CustomControls:DiscreteSlider x:Name="slider" Grid.Column="1">
  <CustomControls:DiscreteSlider.Value>
    <MultiBinding Mode="TwoWay">
      <MultiBinding.Converter>
        <WinConverters:FeatureConverter />
      </MultiBinding.Converter>
      <Binding Path="Enabled" />
      <Binding Path="Value" />
      <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:DialogBase}}" />
  </MultiBinding>

这是一个类似滑块的用户控件(“DiscreteSlider”)的绑定,它在后面的代码中有以下代码(控件实际上包装了一个滑块并对其执行操作):

public static readonly DependencyProperty ValueProperty =
    DependencyProperty.Register(
        "Value",
        typeof(double),
        typeof(DiscreteSlider),
        new FrameworkPropertyMetadata((double)0.0,
            FrameworkPropertyMetadataOptions.AffectsRender,
            new PropertyChangedCallback(OnValueChanged)));

public double Value
{
    get { return (double)GetValue(ValueProperty); }
    set { SetValue(ValueProperty, value); }
}

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    DiscreteSlider obj = d as DiscreteSlider;
    if (obj != null)
    {
        double oldValue = (double)e.OldValue;
        double newValue = (double)e.NewValue;
        obj._Slider.Value = newValue;
        obj.DoValueChanged(oldValue, newValue);
    }
}

private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
    _IsUserChange = true;
    Value = _Slider.Value;
}

发生的事情是该值实际上并未更新。已_Slider.Value正确设置,但在将 Value 分配给它之后, Value 未更改。

关于/围绕此代码的唯一变化是我们从 .NET 3.5 升级到 4.0。我能够通过Mode="TwoWay"从 XAML 中的多重绑定中删除来“修复”这个问题。但是,我不能忍受巧合的编程。我想知道为什么会这样。

有没有人知道为什么这个 XAML 和代码在 3.5 而不是 4 中起作用的解释?如果您能想到一些其他可能的解释,我很乐意听到它,但是自从它在 3.5 中部署(和功能)以来,XAML 和该控件背后的代码都没有改变。

编辑

以下是相关值转换器的代码:

public class FeatureConverter : IMultiValueConverter
{
    private bool Enabled = true;
    private const int MinValue = MelodyConst.MinValue;

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values == null || values.Count() < 2) return null;

        double returnValue = MelodyConst.DisabledValue;

        bool featureEnabled;
        Int32 featureValue;

        bool.TryParse(values[0].ToString(), out featureEnabled);
        Int32.TryParse(values[1].ToString(), out featureValue);

        Enabled = featureEnabled;

        if (!featureEnabled)
            return returnValue;
        else
            returnValue = (double)(featureValue);

        return returnValue;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        Int32 newSliderValue;
        Int32.TryParse(value.ToString(), out newSliderValue);

        object[] lsValues = new object[2];
        lsValues[0] = (object)Enabled;
        lsValues[1] = newSliderValue;

        return lsValues;
    }
}
4

2 回答 2

3

我没有亲身经历过您遇到的问题。但根据ScottGu的博客,Xaml/Baml 解析器已被 WPF 4.0 中的新解析器所取代。因此,完全有可能在 3.5 和 4.0 之间存在一些重大变化,尽管我没有找到任何关于您的问题的具体参考。

从上面的博客。

WPF 4 已将其 XamlReader.Load()、BAML 加载、控制和 DataTemplates 功能的实现替换为构建在新 System.Xaml.dll 之上的新引擎。作为这项工作的一部分,我们修复了许多错误并进行了许多功能改进。

于 2012-02-22T07:10:28.337 回答
0

我认为这可能会发生,因为您将三个值绑定到 MultiValue 转换器,但在 ConvertBack 方法中您只返回两个值;您可以尝试删除第三个绑定,因为您无论如何都不使用它。

如果转换器没有返回正确数量的参数,4.0 中可能发生了一些变化,这会导致绑定失败,但我不确定这一点。

于 2012-02-21T06:20:16.483 回答