代码之家  ›  专栏  ›  技术社区  ›  TerrorAustralis

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

  •  1
  • TerrorAustralis  · 技术社区  · 15 年前

    我正在尝试将序列绑定添加到VisioFire图形控件集。为此,我创建了时间的序列源依赖属性 DataSeriesCollection . 在前端使用以下方法绑定:

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

    问题
    当源更改时,将调用验证回调。传递给它的值是正确的值,填充 ObservableCollection<something> . 在调用validate值后,立即由某个对象调用强制值回调,发送给它的值为空 可观察收集<something> . 任何人只要能:

    1. 正确填充 ObservableCollection<someting> 传递到强制值回调或
    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;
        }
    

    新信息
    强制值回调接收的值始终是该属性设置为的第一个值。因此,如果我传递的第一个值是一个包含1个项的列表,它将始终强制值返回包含一个项的列表!

    编辑:发现问题,它在属性更改回调中。马特帮助我完成了强制回拨。

    1 回复  |  直到 15 年前
        1
  •  2
  •   Matt Hamilton    15 年前

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

    不要向setter添加逻辑,而是考虑使用“强制”回调,每次为属性分配值时都会调用该回调。 See here for more details about "coerce value" callbacks. 它们非常类似于您为“属性更改”回调所做的操作。

    推荐文章