【问题标题】:WPF binding not applying to target after initialization初始化后 WPF 绑定未应用于目标
【发布时间】:2011-03-30 06:59:10
【问题描述】:

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

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

问题
当源更改时,将调用验证回调。传递给它的值是正确的值,即填充的ObservableCollection&lt;something&gt;。在调用 validate 值后,CoerceValue 回调立即被某些东西调用,发送给它的值是 EMPTY ObservableCollection&lt;something&gt;。赏金将颁发给任何能够:

  1. 获取传递给 CoerceValue 回调的正确填充 ObservableCollection&lt;someting&gt;
  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 个项目的列表,它总是会强制将该值返回到一个包含一个项目的列表!

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

【问题讨论】:

  • 只是为了确认:您正在检查是否使用图表的 SeriesSource 依赖属性的设置器上的断点设置了值?这行不通 - 数据绑定 DP 上的 getter 和 setter 被绕过。
  • 见上面的代码。我在 OnSeriesChange 函数上使用断点
  • 有时这些事情会自行解决! :) 抱歉,我帮不上忙,但我想至少我帮助了你。

标签: wpf xaml binding dependency-properties


【解决方案1】:

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

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

【讨论】:

  • 嘿,马特,我添加了 CoerceValue 回调,每当绑定更改时都会调用它,但传递给它的对象不是从源返回的对象... Tat 解释说为什么永远不会调用 propertychanged 因为项目总是相同的,一个空白列表
猜你喜欢
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-19
  • 1970-01-01
  • 2021-08-27
  • 2014-08-27
  • 2015-05-06
相关资源
最近更新 更多