Reha Mathur
Reha Mathur

Reputation: 277

Xamarin Forms Data Binding

I am just starting out using Xamarin so I decided to make a project so I could get the hang of things. For my project, I have these details pages which based on which page you select will display a chart and some text with data specific to that page. I was able to display the text quite easily with bindingcontext but I am lost on how I would be able to pass the data for the charts. I am using microcharts to generate the charts.

ItemDetailPage.xaml.cs

using System; 
using Xamarin.Forms;
using System.Collections.Generic;
using Microcharts; 
using Entry = Microcharts.Entry;
using SkiaSharp; 

namespace TestApp
{
    public partial class ItemDetailPage : ContentPage
    {


        List<Microcharts.Entry> entries = new List<Microcharts.Entry>
        {
               new Entry(200)
                {
                    Label = "January",
                    ValueLabel = "200",
                    Color = SKColor.Parse("#266489")
                },
                new Entry(400)
                {
                    Label = "February",
                    ValueLabel = "400",
                    Color = SKColor.Parse("#68B9C0")
                },
                new Entry(-100)
                {
                    Label = "March",
                    ValueLabel = "-100",
                    Color = SKColor.Parse("#90D585")
                }

        };

        ItemDetailViewModel viewModel;

        // Note - The Xamarin.Forms Previewer requires a default, parameterless constructor to render a page.
        public ItemDetailPage()
        {

            Initialize(null); 


        }

        public ItemDetailPage(ItemDetailViewModel viewModel)
        {
            Initialize(viewModel); 
        }

        public void Initialize(ItemDetailViewModel viewModel) {
            InitializeComponent(); 
            Chart1.Chart = new RadialGaugeChart { Entries = entries }; 
            if (viewModel == null) { 
                var item = new Item
                {
                    Text = "Item 1",
                    Description = "This is an item description."
                };

                viewModel = new ItemDetailViewModel(item);

                Console.WriteLine(item.Text);


            }

            BindingContext = viewModel;



        }



    }
}

ItemDetailPage.xaml

    <?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:forms = "clr-namespace:Microcharts.Forms;assembly=Microcharts.Forms" x:Class="TestApp.ItemDetailPage" Title="{Binding Title}">
      <ContentPage.Content> 

        <StackLayout> 


                <Label TextColor="#77d065" FontSize = "20" Text="{Binding Item.Text}" />
                <Label TextColor="#77d065" FontSize = "20" Text="{Binding Item.Info}" />
                <forms:ChartView x:Name="Chart1" HeightRequest = "150"/>  

        </StackLayout>



</ContentPage.Content>
</ContentPage>

ItemDetailViewModel.cs

using System;

namespace TestApp
{
    public class ItemDetailViewModel : BaseViewModel
    {
        public Item Item { get; set; }
        public ItemDetailViewModel(Item item = null)
        {
            Title = item?.Text;
            Item = item;
        }
    }
}

ItemsPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

using Xamarin.Forms;

namespace TestApp
{
    public partial class ItemsPage : ContentPage
    {
        ItemsViewModel viewModel;

        public ItemsPage()
        {
            InitializeComponent();

            BindingContext = viewModel = new ItemsViewModel();
        }

        async void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
        {
            var item = args.SelectedItem as Item;
            if (item == null)
                return;

            await Navigation.PushAsync(new ItemDetailPage(new ItemDetailViewModel(item)));

            // Manually deselect item
            ItemsListView.SelectedItem = null;
        }

        async void AddItem_Clicked(object sender, EventArgs e)
        {
            await Navigation.PushAsync(new NewItemPage());
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();

            if (viewModel.Items.Count == 0)
                viewModel.LoadItemsCommand.Execute(null);
        }
    }
}

Items List

   items = new List<Item>();
        var mockItems = new List<Item>
        {
            new Item { Id = Guid.NewGuid().ToString(), Text = "First item", Description="This is an item description.", Info = "Some More Info", label1 = "value1" },
            new Item { Id = Guid.NewGuid().ToString(), Text = "Second item", Description="This is an item description.",label1 = "value2" },
            new Item { Id = Guid.NewGuid().ToString(), Text = "Third item", Description="This is an item description.", label1 = "value3" },
            new Item { Id = Guid.NewGuid().ToString(), Text = "Fourth item", Description="This is an item description." },
            new Item { Id = Guid.NewGuid().ToString(), Text = "Fifth item", Description="This is an item description." },
            new Item { Id = Guid.NewGuid().ToString(), Text = "Sixth item", Description="This is an item description." },
        };

So like my goal for example would be to have the label for one of the entries in the chart correspond to the label1 value of item.

If anybody could point me in the right direction on how to accomplish this, that would be very nice.

Upvotes: 1

Views: 1373

Answers (2)

just add this line and set the value the size to say in this example is 20f, but it can be anyone who serves you

Chart1.Chart.LabelTextSize = 30f;

Upvotes: 0

Ax1le
Ax1le

Reputation: 6641

You have got the ItemDetailViewModel in the method Initialize(...), so you can use your item passed from ItemsPage to customize your charts like:

// Do not use the default entries
Chart1.Chart = new RadialGaugeChart(); //{ Entries = entries };

// Modify the entry in entries(for instance the first one)
var singleEntry = entries[0];

Microcharts.Entry entry = new Microcharts.Entry(float.Parse(viewModel.Item.label1))
{
    Label = singleEntry.Label,
    ValueLabel = viewModel.Item.label1,
    Color = singleEntry.Color
};
entries[0] = entry;
// At last initialize the chart's Entries 
Chart1.Chart.Entries = entries;

Upvotes: 1

Related Questions