none
Xamarin BindableProperty Uygulamak RRS feed

  • Soru

  • Merhaba arkadaşlar.

    Linkteki son cevapta bir bindableproperty verilmiş. Bunu kendi label'ıma nasıl uygulayacağımı bilmiyorum. Yardımcı olabilir misiniz?

    Sitedeki kod:

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Xamarin.Forms;
    
    namespace MyApp.Behaviors
    {
        public class NumericTextAnimationBehavior : Behavior<Label>
        {
            public const int DefaultDuration = 1000;
    
            public const int DefaultTick = 25;
    
            private CancellationTokenSource _cancellationTokenSource;
    
            private float _currentValue = 0;
    
            public static readonly BindableProperty ValueProperty =
                BindableProperty.Create(
                    nameof(Value),
                    typeof(float),
                    typeof(NumericTextAnimationBehavior),
                    propertyChanged: ValueChanged);
    
            public float Value
            {
                get { return (float)GetValue(ValueProperty); }
                set { SetValue(ValueProperty, value); }
            }
    
            public static readonly BindableProperty DurationProperty =
                BindableProperty.Create(
                    nameof(Duration),
                    typeof(int),
                    typeof(NumericTextAnimationBehavior),
                    DefaultDuration);
    
            public int Duration
            {
                get { return (int)GetValue(DurationProperty); }
                set { SetValue(DurationProperty, value); }
            }
    
            public static readonly BindableProperty TickProperty =
                BindableProperty.Create(
                    nameof(Tick),
                    typeof(int),
                    typeof(NumericTextAnimationBehavior),
                    DefaultTick);
    
            public int Tick
            {
                get { return (int)GetValue(TickProperty); }
                set { SetValue(TickProperty, value); }
            }
    
            public Label AssociatedObject { get; private set; }
    
            protected override void OnAttachedTo(Label bindable)
            {
                base.OnAttachedTo(bindable);
                AssociatedObject = bindable;
    
                if (bindable.BindingContext != null)
                {
                    BindingContext = bindable.BindingContext;
                }
    
                bindable.BindingContextChanged += OnBindingContextChanged;
            }
    
            protected override void OnDetachingFrom(Label bindable)
            {
                base.OnDetachingFrom(bindable);
                AssociatedObject = null;
    
                bindable.BindingContextChanged -= OnBindingContextChanged;
            }
    
            void OnBindingContextChanged(object sender, EventArgs e)
            {
                OnBindingContextChanged();
            }
    
            protected override void OnBindingContextChanged()
            {
                base.OnBindingContextChanged();
                BindingContext = AssociatedObject.BindingContext;
            }
    
            private static void ValueChanged(BindableObject bindable, object oldValue, object newValue)
            {
                var behavior = (NumericTextAnimationBehavior)bindable;
                behavior.AnimateText();
            }
    
            private void AnimateText()
            {
                Interlocked.Exchange(ref this._cancellationTokenSource, new CancellationTokenSource())?.Cancel();
    
                var cancellationToken = _cancellationTokenSource.Token;
    
                try
                {
                    Task.Run(() => ExecuteAnimateText(cancellationToken), cancellationToken);
                }
                catch (OperationCanceledException)
                {
                }
            }
    
            private void ExecuteAnimateText(CancellationToken cancellationToken)
            {
                var numberOfSteps = Duration / Tick;
    
                if (_currentValue < Value)
                {
                    var step = (float)Math.Max(.01d, (Value - _currentValue) / numberOfSteps);
                    while (_currentValue < Value)
                    {
                        if (cancellationToken.IsCancellationRequested)
                            return;
    
                        if ((_currentValue + step) <= Value)
                            _currentValue += step;
                        else
                            _currentValue = Value;
    
                        Device.BeginInvokeOnMainThread(() => AssociatedObject.Text = _currentValue.ToString("C"));
    
                        Thread.Sleep(Tick);
                    }
                }
                else if (_currentValue > Value)
                {
                    var step = (float)-Math.Max(.01d, (_currentValue - Value) / numberOfSteps);
                    while (_currentValue > Value)
                    {
                        if (cancellationToken.IsCancellationRequested)
                            return;
    
                        if ((_currentValue + step) >= Value)
                            _currentValue += step;
                        else
                            _currentValue = Value;
    
                        Device.BeginInvokeOnMainThread(() => AssociatedObject.Text = _currentValue.ToString("C"));
    
                        Thread.Sleep(Tick);
                    }
                }
            }
        }
    }

    Eklemeye çalıştığım xaml kodu:

         <Label x:Name="lblScore"  FontSize="24">
                                <Label.Behaviors>
                                    <controls:NumericTextAnimationBehavior Value="{Binding Number}" BindingContext="{Binding BindingContext, Source={x:Reference lblScore}}"/>
                                </Label.Behaviors>
                            </Label>

    cs kodu:

            private String _number;
            public String Number
            {
                get { return _number; }
                set
                {
                    _number = value;
                    NotifyPropertyChanged();
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected virtual void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
            {
                var handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs(propertyName));
            }
    
    
            private void btnSetRandom_Clicked(object sender, EventArgs e)
            {
                Random randomizer = new Random();
                Number = randomizer.Next(1, 9999).ToString();
            }


    -

    12 Kasım 2019 Salı 08:27

Yanıtlar