Xamarin.Forms.DataGrid icon indicating copy to clipboard operation
Xamarin.Forms.DataGrid copied to clipboard

CellTemplate custom object binding

Open Goncharuk-Nikita opened this issue 6 years ago • 5 comments

Hi!

I want to bind the JobObject object to the CellTemplate:

public class JobObject
    {
        public int JobId { get; set; }
        public bool IsMine { get; set; }
        public DateTime Start { get; set; }
        public List<MonteurObject> Monteurs { get; set; }
        public bool IsProtocolSent { get; set; }
        public string Color { get; set; }

        public override string ToString()
        {
            return $"{JobId}. Start: {Start.ToShortDateString()}, Color: {Color}";
        }
    }

But when I bind a list, nothing is displayed

<ContentView.Resources>
		<ResourceDictionary>

			<DataTemplate x:Key="JobCellTemplate">
				<ViewCell>
					<Label
						HorizontalOptions="Center"
						Text="{Binding JobMon.JobId}"
						VerticalOptions="Center" />
				</ViewCell>
			</DataTemplate>

			<Style TargetType="dg:DataGridColumn">
				<Setter Property="CellTemplate" Value="{StaticResource JobCellTemplate}" />
			</Style>


		</ResourceDictionary>
	</ContentView.Resources>

<!--  Data  -->
		<dg:DataGrid
			BindingContext="{x:Reference This}"
			BorderColor="Gray"
			HeaderHeight="50"
			IsSortable="False"
			ItemsSource="{Binding WeekItems.JobRows}"
			RowHeight="70"
			SelectionEnabled="True">

			<dg:DataGrid.Columns>
				<dg:DataGridColumn Title="{Binding WeekItems.DaysOfMonth[0], StringFormat=' {0}&#10;Mon'}" PropertyName="JobMon" />
				<dg:DataGridColumn Title="{Binding WeekItems.DaysOfMonth[1], StringFormat=' {0}&#10;Tue'}" PropertyName="JobTue" />
				<dg:DataGridColumn Title="{Binding WeekItems.DaysOfMonth[2], StringFormat=' {0}&#10;Wed'}" PropertyName="JobWed" />
				<dg:DataGridColumn Title="{Binding WeekItems.DaysOfMonth[3], StringFormat=' {0}&#10;Thu'}" PropertyName="JobThu" />
				<dg:DataGridColumn Title="{Binding WeekItems.DaysOfMonth[4], StringFormat=' {0}&#10;Fri'}" PropertyName="JobFri" />
				<dg:DataGridColumn Title="{Binding WeekItems.DaysOfMonth[5], StringFormat=' {0}&#10;Sat'}" PropertyName="JobSat" />
				<dg:DataGridColumn Title="{Binding WeekItems.DaysOfMonth[6], StringFormat=' {0}&#10;Sun'}" PropertyName="JobSun" />
			</dg:DataGrid.

Goncharuk-Nikita avatar Mar 15 '18 06:03 Goncharuk-Nikita

Hi,

Could you please give more details.

  • Can you also share Xaml.cs code so I can see the typeof WeekItems.JobRows

akgulebubekir avatar Mar 15 '18 07:03 akgulebubekir

@akgulebubekir

ScheduleWeekView.xaml.cs:

#region BindableProperties
public partial class ScheduleWeekView : ContentView
	{
	    public static readonly BindableProperty WeekItemsProperty = BindableProperty.Create(
			"WeekItems",
	        typeof(WeekInfo),
	        typeof(ScheduleWeekView));

		public static readonly BindableProperty ItemTappedCommandProperty = BindableProperty.Create(
			"ItemTappedCommand",
			typeof(ICommand),
			typeof(ScheduleWeekView));

		#endregion


		#region Public Fields

		public ICommand ItemTappedCommand
		{
			get => (ICommand)GetValue(ItemTappedCommandProperty);
			set => SetValue(ItemTappedCommandProperty, value);
		}

		public WeekInfo WeekItems
		{
		    get => (WeekInfo) GetValue(WeekItemsProperty);
			set => SetValue(WeekItemsProperty, value);
	    }
}
		#endregion

AllJobsPage.xaml:

<base:ContentBasePage
	x:Class="MDOSchedule.UI.Pages.AllJobs.AllJobsWeekPage"
	xmlns="http://xamarin.com/schemas/2014/forms"
	xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
	xmlns:base="clr-namespace:MDOSchedule.UI.Pages.Base;assembly=MDOSchedule"
	xmlns:extensions="clr-namespace:MDOSchedule.Extensions;assembly=MDOSchedule"
	xmlns:week="clr-namespace:MDOSchedule.UI.Views.Week;assembly=MDOSchedule"
	Title="{extensions:Translate AllJobsWeekPageTitle}">

	<ContentPage.ToolbarItems>
		<ToolbarItem
			Command="{Binding RefreshItemsCommand}"
			Icon="ic_refresh.png"
			Order="Primary" />
	</ContentPage.ToolbarItems>

	<ContentPage.Content>
		<week:ScheduleWeekView ItemTappedCommand="{Binding JobTappedCommand}" WeekItems="{Binding WeekJobs}" />
	</ContentPage.Content>
</base:ContentBasePage>

AllJobsViewModel.cs

public class AllJobsWeekViewModel : BaseViewModel
   {
		#region Public Fields

		public WeekInfo WeekJobs
		{
			get => Get<WeekInfo>();
			set => Set(value);
		}

		#endregion


		#region Commands

		public ICommand JobTappedCommand => new Command<JobObject>(NavigateToJobDetail);

       public ICommand RefreshItemsCommand => MakeCommand(RefreshItems);


       private void NavigateToJobDetail(JobObject jo)
       {

       }

       private void RefreshItems()
       {

       }

       #endregion


       #region Override Methods

       public override async Task OnPageAppearing()
       {

			var rowData = GetTestData();
	        var days = new List<string> {"14", "15", "16", "17", "18", "19", "20"};

			WeekJobs = new WeekInfo(rowData, days);

	        await Task.FromResult(0);	       
       }

       #endregion

       #region Test

       public List<JobRow> GetTestData()
       {
	        var rows = new List<JobRow>();

			for (int i = 0; i < 16; i++)
			{
				var row = new JobRow(
					i < 12 ? new JobObject() {Color = "#f99472", JobId = 42} : null,
					new JobObject() {Color = "#b6ff7c", JobId = 62 },
					i < 5 ? new JobObject() {Color = "#b6ff7c", JobId = 42 } : null,
					new JobObject() {Color = "#f99472", JobId = 52 },
					i < 14 ? new JobObject() {Color = "#f99472", JobId = 12 }: null,
					new JobObject() {Color = "#b6ff7c", JobId = 42 },
					i < 5 ? new JobObject() { Color = "#b6ff7c", JobId = 42 } : null);
				rows.Add(row);
			}

	        return rows;
       }

       #endregion
   }

Models

WeekInfo.cs:

public class WeekInfo
    {
		public List<JobRow> JobRows { get; set; }

		public List<string> DaysOfMonth { get; set; }

	    public WeekInfo(List<JobRow> jobRows, List<string> daysOfMonth)
	    {
		    JobRows = jobRows;
		    DaysOfMonth = daysOfMonth;
	    }
    }

JobRow.cs

public class JobRow
    {
		public JobObject JobMon { get; set; }
		public JobObject JobTue { get; set; }
		public JobObject JobWed { get; set; }
		public JobObject JobThu { get; set; }
		public JobObject JobFri { get; set; }
		public JobObject JobSat { get; set; }
		public JobObject JobSun { get; set; }

	    public JobRow() { }

	    public JobRow(params JobObject[] jobs)
	    {
		    JobMon = jobs[0];
		    JobTue = jobs[1];
		    JobWed = jobs[2];
		    JobThu = jobs[3];
		    JobFri = jobs[4];
		    JobSat = jobs[5];
		    JobSun = jobs[6];
	    }
    }

JobObject.cs:

public class JobObject
    {
        public int JobId { get; set; }
        public bool IsMine { get; set; }
        public DateTime Start { get; set; }
        public List<MonteurObject> Monteurs { get; set; }
        public bool IsProtocolSent { get; set; }
        public string Color { get; set; }

        public override string ToString()
        {
            return $"{JobId}. Start: {Start.ToShortDateString()}, Color: {Color}";
        }
    }

I checked and all the data comes in the DataGrid

Goncharuk-Nikita avatar Mar 15 '18 08:03 Goncharuk-Nikita

im having the same issue, im creating a custom datatemplate for my cell, but if I set the PropertyName on the column then nothing is showing up in the cell. Its not binding inside the datatemplate. Did you manage to get this working in the end?

riaanvdl avatar Aug 19 '18 22:08 riaanvdl

Once you set the PropertyName for the column, it set that property as binding context. You don't need to specify again. It should be working once you replace Text="{Binding JobMon.JobId}" with Text="{Binding JobId}" as below

<DataTemplate x:Key="JobCellTemplate">
	<ViewCell>
		<Label
			HorizontalOptions="Center"
			Text="{Binding JobId}"
			VerticalOptions="Center" />
	</ViewCell>
</DataTemplate>

akgulebubekir avatar Aug 20 '18 06:08 akgulebubekir

When using datatemplate I need to deactivate "IsSortable" on the grid because I will get exception with "Please set the PropertyName property of Column", when I try to sort by tapping on the header column. I don't know how to make the Datagrid use sortable having DataTemplates for the columns. I think my issue is similar.

dasdingo avatar Apr 08 '19 18:04 dasdingo