WPF binding not applying to target after initialization

I am trying to add Series binding to the Visifire graphing controls set. To this end i have created a SeriesSource dependency property of time DataSeriesCollection . This is bound in the front end using:

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

Problem
When the source changes, the validation callback is called. The value that is passed to this is the correct value, a populated ObservableCollection<something> . Immediately after the validate value is called, the CoerceValue callback is called by something, and the value that is sent to it is an EMPTY ObservableCollection<something> . Bounty will go to anyone who can:

  • Get the correct populated ObservableCollection<someting> passed to the CoerceValue callback OR
  • Get the correct value being passed to the OnSeriesSourceChanged callback OR
  • Explain to me how i can do any of the above :)
  • Here is the data template for the view:

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

    Here is the target Dependency Property

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

    New information
    The value being received by the CoerceValue callback is ALWAYS the first value which that property was set to. So if the first value i pass it is a list with 1 item, it will always coerce the value back to a list with one item!

    Edit: found the issue, it was in the property changed callback. Credit goes to Matt for helping me out with the CoerceValue callback


    This may not be the exact problem, but you have logic in your setter. That code isn't going to be executed when the property is assigned via a binding.

    Instead of adding logic to your setter, consider using a "coerced" callback which gets called every time a value is assigned to your property. See here for more details about "coerce value" callbacks. They're very similar to what you've done for your "property changed" callback.

    链接地址: http://www.djcxy.com/p/67568.html

    上一篇: 未设置DataContext时发生WPF绑定问题

    下一篇: 初始化后WPF绑定不适用于目标