初始化后WPF绑定不应用于目标

时间:2010-08-16 06:12:58

标签: wpf xaml binding dependency-properties

我正在尝试将系列绑定添加到Visifire图形控件集。为此,我创建了一个时间DataSeriesCollection的SeriesSource依赖项属性。这在前端绑定使用:

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

问题
当源更改时,将调用验证回调。传递给它的值是正确的值,即填充的ObservableCollection<something>。在调用validate值之后,CoerceValue回调会立即调用,并且发送给它的值是EMPTY ObservableCollection<something>。赏金将交给任何能够:

的人
  1. 获取传递给CoerceValue回调的正确填充ObservableCollection<someting>
  2. 获取传递给OnSeriesSourceChanged回调的正确值或
  3. 向我解释我如何能够做到以上任何一项:)
  4. 以下是视图的数据模板:

    <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个项目的列表,它将始终将值强制回到包含一个项目的列表中!

    编辑:发现问题,它在属性中更改了回调。感谢Matt帮我解决了CoerceValue回调问题

1 个答案:

答案 0 :(得分:2)

这可能不是确切的问题,但你的setter中有逻辑。通过绑定分配属性时,不会执行该代码。

不要在setter中添加逻辑,而是考虑使用“强制”回调,每次为您的属性赋值时都会调用该回调。 See here for more details about "coerce value" callbacks.它们与您为“财产更改”回调所做的非常相似。