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

在WPF升级后,OnPropertyChanged调用了更多

  •  0
  • Zoli  · 技术社区  · 7 年前


    在WPF 3.0中,它运行良好。
    现在我们转到WPF 4.5,同样的代码也可以运行 :编辑单元格并按ENTER键后,会导致网格“额外刷新”。

    public List<List<double>> DoubleArray { get; set; }
    
    private void dataGrid2D_CellEditEnding(object sender, Microsoft.Windows.Controls.DataGridCellEditEndingEventArgs e)
    {
         ...
         DoubleArray[y][x] = double.Parse(textBox.Text);
         GridContent = DoubleArray; <======= [this line]
         ...
    }
    
    public static readonly DependencyProperty GridContentProperty =
            DependencyProperty.Register("GridContent", typeof(IList), typeof(GridEditor), 
                                 new UIPropertyMetadata(null,GridContentPropertyChanged));
    
    public IList GridContent
    {
        get { return (IList)GetValue(GridContentProperty); }
        set { SetValue(GridContentProperty, value); }
    }
    
    private static void GridContentPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        GridEditor editor = source as GridEditor;
        editor.OnGridContentChanged(e.OldValue,e.NewValue);
    }
    
    public virtual void OnGridContentChanged(object oldValue, object newValue)
    {
         ....
         RebindData(dataGrid);
    }
    
    private void RebindData(DataGrid2DLibrary.DataGrid2DT grid)
    {
        Binding datagrid2dBinding = new Binding();
        .....
        datagrid2dBinding.Path = new PropertyPath("DoubleArray");
        grid.SetBinding(DataGrid2DT.ItemsSource2DProperty, datagrid2dBinding);
     }
    

    GridContent = DoubleArray; 在WPF3和WPF4.5中运行不同。
    在WPF4.5中,它会导致 GridContentPropertyChanged
    此“额外”调用的调用堆栈:

    OurEditor.dll!OurEditor.GridEditor.GridEditor.OnGridContentChanged(object oldValue, object newValue) Line 345   C#
    OurEditor.dll!OurEditor.GridEditor.GridEditor.GridContentPropertyChanged(System.Windows.DependencyObject source, System.Windows.DependencyPropertyChangedEventArgs e) Line 120  C#
    WindowsBase.dll!System.Windows.DependencyObject.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e)  Unknown
    PresentationFramework.dll!System.Windows.FrameworkElement.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e)    Unknown
    WindowsBase.dll!System.Windows.DependencyObject.NotifyPropertyChange(System.Windows.DependencyPropertyChangedEventArgs args)    Unknown
    WindowsBase.dll!System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex entryIndex, System.Windows.DependencyProperty dp, System.Windows.PropertyMetadata metadata, System.Windows.EffectiveValueEntry oldEntry, ref System.Windows.EffectiveValueEntry newEntry, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType) Unknown
    WindowsBase.dll!System.Windows.DependencyObject.InvalidateProperty(System.Windows.DependencyProperty dp, bool preserveCurrentValue) Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.Invalidate(bool isASubPropertyChange)   Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpression.TransferValue(object newValue, bool isASubPropertyChange)   Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpression.ScheduleTransfer(bool isASubPropertyChange) Unknown
    PresentationFramework.dll!MS.Internal.Data.ClrBindingWorker.NewValueAvailable(bool dependencySourcesChanged, bool initialValue, bool isASubPropertyChange)  Unknown
    PresentationFramework.dll!MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(int k, System.ComponentModel.ICollectionView collectionView, object newValue, bool isASubPropertyChange)   Unknown
    PresentationFramework.dll!MS.Internal.Data.PropertyPathWorker.RefreshValue()    Unknown
    PresentationFramework.dll!MS.Internal.Data.ClrBindingWorker.RefreshValue()  Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpression.UpdateTarget()  Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.EndSourceUpdate()   Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpression.UpdateSource(object value)  Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.UpdateValue()   Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpression.UpdateOverride()    Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.Update()    Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.ProcessDirty()  Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.Dirty() Unknown
    PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.SetValue(System.Windows.DependencyObject d, System.Windows.DependencyProperty dp, object value) Unknown
    WindowsBase.dll!System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty dp, object value, System.Windows.PropertyMetadata metadata, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType, bool isInternal)    Unknown
    WindowsBase.dll!System.Windows.DependencyObject.SetValue(System.Windows.DependencyProperty dp, object value)    Unknown
    OurEditor.dll!OurEditor.GridEditor.GridEditor.GridContent.set(System.Collections.IList value) Line 114  C#
    OurEditor.dll!OurEditor.GridEditor.GridEditor.dataGrid2D_CellEditEnding(object sender, Microsoft.Windows.Controls.DataGridCellEditEndingEventArgs e) Line 674   C#
    

    <ControlTemplate x:Key="GridEditorTemplate">
        <ge:GridEditor IsReadOnly="{Binding IsOutput, RelativeSource={RelativeSource AncestorType={x:Type vo:OutputView}}}">
            <me:GridEditor.GridContent>
                <Binding Path="TheGridValue"  Mode="TwoWay" Converter="{StaticResource gridConverter}">
                </Binding> 
             </me:GridEditor.GridContent>
        </me:GridEditor>
    </ControlTemplate>
    


    如果需要任何其他信息,我可以尝试提供。

    1 回复  |  直到 7 年前
        1
  •  0
  •   mm8    7 年前

    GridContentPropertyChanged

    嗯,这个 GridContentPropertyChanged

    当你升级.NET版本时,你可能会“免费”得到很多修复。如果这导致应用程序中出现问题,那么您的代码可能最初是以错误的方式编写的。因此,您可以避免升级或按照@Peter的建议修复代码:

    public virtual void OnGridContentChanged(object oldValue, object newValue)
    {
        if (oldvalue == newValue)
            return;
         ....
         RebindData(dataGrid);
    }