Привязка WPF не применяется к цели после инициализации

Я пытаюсь добавить привязку Series к набору графических элементов управления Visifire. Для этого я создал свойство зависимости SeriesSource времени DataSeriesCollection . Это связывается во внешнем интерфейсе с помощью:

`<Chart SeriesSource={Binding Series} />`  

Задача
При изменении источника вызывается обратный вызов проверки. Значение, которое передается этому, является правильным значением, заполненным ObservableCollection <что-то> . Сразу после вызова значения проверки вызывается обратный вызов CoerceValue чем-то, и отправляемое ему значение является ПУСТОЙ ObservableCollection <что-то> . Баунти достанется любому, кто может:

  1. Получить правильное заполненное значение ObservableCollection , переданное в обратный вызов CoerceValue ИЛИ
  2. Получить правильное значение, передаваемое в обратный вызов OnSeriesSourceChanged ИЛИ
  3. Объяснить для мне, как я могу сделать что-либо из перечисленного выше:)

Вот шаблон данных для представления:

<DataTemplate DataType="{x:Type vm:ReportViewModel}">
    <Grid Name="rootGrid">
    <visifire:Chart Grid.Row="1" SeriesSource="{Binding Series}">
        <visifire:Chart.AxesX>
                <visifire:Axis Title="X axis" />
        </visifire:Chart.AxesX>
        <visifire:Chart.AxesY>
                <visifire:Axis Title="Y axis" />
        </visifire:Chart.AxesY>
    </visifire:Chart>
    </Grid>
</DataTemplate>

Вот целевое свойство зависимости

    //Getter and setter for Dependency Property
    public ObservableCollection<DataSeries> SeriesSource
    {
        get { return (ObservableCollection<DataSeries>)GetValue(SeriesSourceProperty); }
        set { SetValue(SeriesSourceProperty, value);           }
    }

    // Using a DependencyProperty as the backing store for SeriesSource.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SeriesSourceProperty =
        DependencyProperty.Register("SeriesSource", typeof(ObservableCollection<DataSeries>), typeof(Chart), new UIPropertyMetadata(new ObservableCollection<DataSeries>(), new PropertyChangedCallback(OnSeriesSourceChange), new CoerceValueCallback(CoerceSeries)), new ValidateValueCallback(ValidateSeriesSource));

    //Value validation callback
    private static bool ValidateSeriesSource(object value)
    {
        if (value as ObservableCollection<DataSeries> != null)
            return true;
        return false;
    }

    //Dependency Property Changed callback
    private static void OnSeriesSourceChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Chart c = d as Chart;
        if (c == null)
            return;
        //This line was causing the issue. It was overriding the setter
        c.SeriesSource = (DataSeriesCollection)e.NewValue;
    }

    //Coerce Value callback
    private static object CoerceSeries(DependencyObject d, object value)
    {
        Chart c = d as Chart;
        var collection = value as System.Collections.ObjectModel.ObservableCollection<Visifire.Charts.DataSeries>;
        foreach (var item in c.Series)
        {
            if (!collection.Contains(item))
                c.Series.Remove(item);
        }
        foreach (var item in collection)
        {
            if (!c.Series.Contains(item))
                c.Series.Add(item);
        }
        return collection;
    }

Новая информация
Значение, получаемое обратным вызовом CoerceValue, ВСЕГДА первое значение, которому было присвоено это свойство. Поэтому, если первое значение, которое я передаю, это список с 1 элементом, оно всегда будет приводить значение обратно к списку с одним элементом!

Редактировать: обнаружена проблема, это было в свойстве измененного обратного вызова. Благодарим Мэтта за то, что он помог мне с обратным вызовом CoerceValue

1
задан TerrorAustralis 16 August 2010 в 23:47
поделиться

1 ответ

Это может быть не совсем проблема, но у вас есть логика в вашем сеттере. Этот код не будет выполняться, когда свойство назначается через привязку.

Вместо добавления логики к сеттеру рассмотрите возможность использования «принудительного» обратного вызова, который вызывается каждый раз, когда значение присваивается вашему свойству. См. Здесь для получения дополнительных сведений об обратных вызовах "принуждение значения". Они очень похожи на то, что вы сделали для обратного вызова "свойство изменено".

2
ответ дан 2 September 2019 в 22:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: