0
votes

I have a page in which I display two different charts, depending on a button click. At the moment I change charts this way:

    protected void ClickedChangeChart()
    {
        if (chartType == true) 
        {
            chartType = false;
            Navigation.PushAsync (new MainPage (false));
        } 

        else 
        {
            chartType = true;
            Navigation.PushAsync (new MainPage (true));
        }
    }

chartType is a bool and depending on it's value I choose which chart to load using this statement in OnAppearing():

protected override async void OnAppearing ()
{
// some code
    ChartView chartView = new ChartView 
    { 
    VerticalOptions = LayoutOptions.FillAndExpand, 
    HorizontalOptions = LayoutOptions.FillAndExpand,
    HeightRequest = 300,
    WidthRequest = 400
    }; 

    if (chartType == true)//true = candle
    { 
        candleModel = new CandleModel ();
        chartView.Model = await candleModel.GetModel ();
    } 

    else if(chartType == false) //false = line
    {
        lineModel = new LineModel ();
        chartView.Model = await lineModel.GetModel ();
    }

    //here I create a grid, add some children to it and the add the chartView
    grid.Children.Add (chartView, 1, 6, 1, 3);

    Content = grid;
}

The problem is that when I want to switch the charts I have to reload the whole page, which isn't what I want. How can I make it so when I click a button I calls a function which switches the model for the chart? I suppose it will be something like this, but I can't get it to work:

    public async void ClickedButton()
    {
        grid.Children.Remove(chartView);

        if (chartType == true)
        { 
            candleModel = new CandleModel ();
            chartView.Model = await candleModel.GetModel ();
        } 

        else if(chartType == false)
        {
            lineModel = new LineModel ();
            chartView.Model = await lineModel.GetModel ();
        }
        grid.Children.Add(chartView);
    }

UPDATE: Using Daniel Luberda's solution, I managed to get it to work with this:

btnChartType.Clicked += async delegate {
    Device.BeginInvokeOnMainThread (async () => {
        grid.Children.Remove (chartView);

        if (isCandle == true) { 
            candleModel = new CandleModel ();
            chartView.Model = await candleModel.GetModel ();
            isCandle = false;
        } else if (isCandle == false) {
            lineModel = new LineModel ();
            chartView.Model = await lineModel.GetModel ();
            isCandle = true;
        }
                grid.Children.Add (chartView, 1, 6, 1, 3); 
    });
};
1

1 Answers

0
votes

You can't get it to work because you have an async method which means that you're doing it on another thread. You can change UI only from UI thread. Also async void will swallow all exceptions, it's better to use async Task instead.

// THAT WILL WORK

public async void ClickedButton() // but public async Task would be better
{
    Device.BeginInvokeOnMainThread(async () => {
        grid.Children.Remove(chartView);

        if (chartType == true)
        { 
            candleModel = new CandleModel ();
            chartView.Model = await candleModel.GetModel ();
        } 

        else if(chartType == false)
        {
            lineModel = new LineModel ();
            chartView.Model = await lineModel.GetModel ();
        }
        grid.Children.Add(chartView);   
    });
}