dotnet/maui

Add OnBindingContextChanging

Open

#24,804 建立於 2024年9月17日

在 GitHub 查看
 (1 留言) (1 反應) (0 負責人)C# (23,245 star) (1,951 fork)batch import
area-xamlgood first issueproposal/opent/enhancement ☀️

描述

Description

I need place in my app to add code before Binding Context changed. As result i should be able to override method OnBindingContextChaging in ContentPage or ContentView.

Public API Changes

public partial class ExamplePage : ContentPage
{
public ExamplePage(ExampleViewModel vm)
{
    BindingContext = vm;
    InitializeComponent();
}
protected override void OnBindingContextChanging(BindingContextChangingEventArgs args)
    {
        //Action before binding context changed
        base.OnBindingContextChanging(args);
    }
}

Intended Use-Case

In my app, I have a sizable CollectionView, where each element is a custom control based on the View. While scrolling, the BindingContext for each element changes dynamically. However, I am only able to respond to the BindingContext after it has changed, and I am unable to react before the context is updated.

example:

public class SparklineChart : GraphicsView
{
    private bool _draw;

    public QuotesData[]? ChartData
    {
        get => (QuotesData[]?)GetValue(ChartDataProperty);
        set => SetValue(ChartDataProperty, value);
    }

    public decimal? Ref
    {
        get => (decimal?)GetValue(RefProperty);
        set => SetValue(RefProperty, value);
    }

    public static readonly BindableProperty ChartDataProperty = BindableProperty.Create(
        propertyName: nameof(ChartData),
        returnType: typeof(QuotesData[]),
        declaringType: typeof(SparklineChart),
        propertyChanged: ChartDataPropertyChanged,
        defaultBindingMode: BindingMode.OneWay);

    public static readonly BindableProperty RefProperty = BindableProperty.Create(
        propertyName: nameof(Ref),
        returnType: typeof(decimal?),
        declaringType: typeof(SparklineChart),
        propertyChanged: RefPropertyChanged,
        defaultBindingMode: BindingMode.OneWay);

    protected override void OnBindingContextChanging(BindingContextChangingEventArgs args)
    {
        _draw = false;
       base.OnBindingContextChanging(args);
    }

    protected override void OnBindingContextChanged()
    {
        _draw = true;
        sparklineChart.Invalidate();
        base.OnBindingContextChanged();
    }

    private static void ChartDataPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        if (bindable is not SparklineChart { Drawable: Sparkline sparkline } sparklineChart)
        {
            return;
        }
        sparkline.ChartData = newValue as QuotesData[];

        if (_draw)
        {
            sparklineChart.Invalidate();
        }
    }

    private static void RefPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        if (bindable is not SparklineChart { Drawable: Sparkline sparkline } sparklineChart)
        {
            return;
        }
        sparkline.Ref = newValue as decimal?;

        if (_draw)
        {
            sparklineChart.Invalidate();
        }
    }
}

貢獻者指南