Переход с.NET 3.5 на 4, похоже, ломает устаревший XAML

В устаревшем компоненте, который я устранял, я наткнулся на следующее:

<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 был установлен правильно, но после того, как ему было присвоено значение, значение не изменилось.

Единственное, что изменилось в / вокруг этого кода, это то, что мы перешли с.NET 3.5 на 4.0. Я смог "исправить" это, удалив Mode="TwoWay" из мультисвязи в XAML. Но я терпеть не могу программирование по совпадению. Я хочу знать, почему это произошло.

Кто-нибудь знает объяснение, почему этот XAML и код будут функционировать в 3.5, а не в 4? Если вы можете придумать какое-то другое потенциальное объяснение, я открыт, чтобы услышать его, но ни XAML, ни код этого элемента управления не изменились с тех пор, как он был развернут (и функционален) в 3.5.

Редактировать:

Вот код для рассматриваемого преобразователя значения:

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;
    }
}

2 ответа

Решение

Я лично не сталкивался с проблемой, с которой вы столкнулись. Но, согласно блогу ScottGu, парсер Xaml/Baml был заменен на новый в WPF 4.0. Так что вполне возможно, что между 3.5 и 4.0 есть некоторые существенные изменения, хотя я не нашел конкретных ссылок на вашу проблему.

Сверху блог.

WPF 4 заменил свою реализацию функций XamlReader.Load(), загрузки BAML, Control & DataTemplates новым механизмом, созданным поверх нового System.Xaml.dll. В рамках этих усилий мы исправили много ошибок и внесли много улучшений в функциональность.

Я думаю, что это может произойти, потому что у вас есть три значения, привязанные к конвертеру MultiValue, но в методе ConvertBack вы возвращаете только два значения; Можете ли вы попробовать удалить третье связывание, поскольку вы все равно не используете его.

Что-то могло измениться в 4.0, что приводит к сбою привязки, если конвертер не возвращает правильное количество параметров, но я не уверен в этом.

Другие вопросы по тегам