首页 > 解决方案 > Xamarin Forms 使用反射获取可绑定属性的属性

问题描述

我想要的是,当值改变时,它应该调用CreateChart()并使用新值。我尝试在 onPropertyChange 方法中调用OnValueChanged具有反射的可绑定属性,但该属性始终为空,并且我没有得到该属性的值Value

public partial class CorrectWrongRingChart : ContentView
    {
        public CorrectWrongRingChart()
        {
            InitializeComponent();
            
            
        }
        
        public static readonly BindableProperty ChartProperty =
            BindableProperty.Create(
                nameof(CorrectWrongChart),
                typeof(Chart),
                typeof(CorrectWrongRingChart));

        public Chart CorrectWrongChart
        {
            get { return (Chart)GetValue(ChartProperty); }
            set => SetValue(ChartProperty, value);
        }

        public static readonly BindableProperty ValueProperty =
          BindableProperty.Create(
              nameof(Value),
              typeof(CorrectWrongValue),
              typeof(CorrectWrongRingChart),
              propertyChanged: OnValueChanged);/*(b, o, n) => { ((CorrectWrongRingChart)b).OnPropertyChanged("Text");});*/

        public  CorrectWrongValue Value
        {
            get { return (CorrectWrongValue)GetValue(ValueProperty); }
            set => SetValue(ValueProperty, value);
        }

        private static void OnValueChanged(BindableObject bindable, object oldValue, object newValue)
        {
             ((CorrectWrongRingChart)bindable).OnPropertyChanged("Text");            
             //((CorrectWrongRingChart)bindable).OnPropertyChanged("Correct"); 
             //((CorrectWrongRingChart)bindable).OnPropertyChanged("Wrong");
            var valueProperty = ValueProperty.GetType().GetProperty("Value");
            var value = (CorrectWrongValue)valueProperty.GetValue("Value");
            var ChartProperty = ValueProperty.GetType().GetProperty("CorrectWrongChart");
            
            if (value != null)
            {

                ChartProperty.SetValue("CorrectWrongChart", CreateChart(value));
                
            }
            
            

        }

        public static readonly BindableProperty TextProperty =
            BindableProperty.Create(
                nameof(Text),
                typeof(string),
                typeof(CorrectWrongRingChart),
                defaultValue: string.Empty);

        public string Text => $"{Value?.CorrectCount ?? 0}/{Value?.TotalCount ?? 0}";
        //public double Correct => Value.CorrectPercentage;
        //public  double Wrong => Value.WrongPercentage;


        private static Chart CreateChart(CorrectWrongValue value)
        {
            var chart = new Microcharts.DonutChart();
            chart.IsAnimated = false;
            
            ChartEntry corretEntry = new ChartEntry((float)value.CorrectPercentage)
            {
                Color = SKColor.Parse("#00FF00")
            };
            ChartEntry wrongEntry = new ChartEntry((float)value.WrongPercentage)
            {
                Color = SKColor.Parse("#FF0000")
            };
            chart.Entries = new List<ChartEntry>() { corretEntry, wrongEntry };
            return chart;
        }
    }

xml:

<Grid >
            <forms:ChartView x:Name="chart1" WidthRequest="130" HeightRequest="130" Chart="{Binding CorrectWrongChart, Source={x:Reference Root}}">
               
</forms:ChartView>
            <Label Text="{ Binding Text, Source={x:Reference Root} }"                  
                   VerticalOptions="Center"
                   HorizontalOptions="Fill"
                   HorizontalTextAlignment="Center"
                   TextColor="Black"
                   FontSize="19"
                   FontFamily="{ StaticResource AppBoldFontFamily }" />
        </Grid>

标签: xamlxamarin.formsreflectionbindableproperty

解决方案


如果你想Value在值改变时得到,你可以像下面这样直接得到它

private static void OnValueChanged(BindableObject bindable, object oldValue, object newValue)
{
    var currentValue = newValue;
   
   // do something you want 
   
    // you could get other property like following 
    // var view = bindable as CorrectWrongRingChart;
    // var currentText = view.Text;


}

当我们改变它的源值时,属性Value会自动改变。所以我们不需要再调用以下行,这可能会导致无限循环。

if (value != null)
{

    ChartProperty.SetValue("CorrectWrongChart", CreateChart(value));
                
}

推荐阅读