1

I am using : https://learn.microsoft.com/en-us/xamarin/essentials/email?tabs=android to send data by email.

I am able to send normal string right now but i have a hard time figuring out how to send the data from my list view, and format them like the picture ( a line for each items).

If someone could give me an idea on how to do this, it would be appreciated.

Note: i just need the text from the each ListView items.

Thanks a lot.

enter image description here

My ListView code

                    <ListView x:Name="listView" ItemsSource="{Binding Tasks}" HasUnevenRows="True" SelectionMode="None">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                    <Frame Margin="0,5,0,5">
                                        <Grid>

                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="*" />
                                                <ColumnDefinition Width="*" />
                                                <ColumnDefinition Width="*" />
                                                <ColumnDefinition Width="*" />
                                            </Grid.ColumnDefinitions>
                                            <Label Grid.Column="0" Margin="0" Text="{Binding TasksGroup.TasksGroupDate, StringFormat='{0:yyyy-MM-dd}'}" FontSize="12" FontAttributes="Bold" TextColor="Black"/>
                                            <Label Grid.Column="1" Margin="0" Text="{Binding TaskDescription}" FontSize="12" FontAttributes="Bold" TextColor="Black" />
                                            <Label Grid.Column="2" Margin="0" Text="{Binding TaskDuration}" FontSize="12" FontAttributes="Bold" TextColor="Black" />
                                            <Label Grid.Column="3" Margin="0" Text="{Binding TaskDBA}" FontSize="12" FontAttributes="Bold" TextColor="Black"/>
                                        </Grid>
                                    </Frame>
                                </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>

My send email method which has other data that was easy to implement because it wasn't listview items

private async void EmailButtonClicked(object sender, EventArgs e)
{

    var message = new EmailMessage
    {
        Subject = "Résultat d'exposition quotidienne",
        Body = DureeTotal.Text + " " + SumTotalHours.Text + h.Text + Environment.NewLine + Environment.NewLine + LeqText.Text + " " + LeqResult.Text + dBA.Text
        + Environment.NewLine + Environment.NewLine + ExpositionResultText.Text + " " + ExpositionResult.Text + dBA8.Text + output
    };
    await Email.ComposeAsync(message);
}

my page ViewModel which has a collection of Tasks and a TasksGroup ( which are the properties that generates the data needed)

class ResultPageViewModel : BaseViewModel
{
    private ObservableCollection<Tasks> tasks;
    public ObservableCollection<Tasks> Tasks
    {
        get
        {
            return tasks;
        }
        set
        {
            tasks = value;
            NotifyPropertyChanged();
        }
    }

    private TasksGroup tasksGroup;
    public TasksGroup TasksGroup
    {
        get => tasksGroup;
        set
        {
            tasksGroup = value;
            NotifyPropertyChanged();
        }
    }


    public ResultPageViewModel(TasksGroup tasksGroup)
    {
        
        TasksGroup = tasksGroup;
        var data = TasksGroup.Taches;
        Sum = TimeSpan.Zero;

        Tasks = new ObservableCollection<Tasks>(data);
        TasksGroup.Taches.ForEach(x =>
        {
            TaskDBA = x.TaskDBA;
            TaskDuration = x.TaskDuration;
            TaskDescription = x.TaskDescription;

            var TaskGroupDuration = Helper.GetDuration(x.TaskDuration);

            Sum = Sum.Add(TaskGroupDuration);
        });
        SumTotalHours += Math.Round(Sum.TotalHours, 4);

        LeqResult = CalculateLeq(tasksGroup);
    }

    public double CalculateLeq(TasksGroup group)
    {
        return Math.Round(10 * Math.Log10((1/SumTotalHours)*group.Taches.Sum(x =>
Helper.GetDuration(x.TaskDuration).TotalHours * Math.Pow(10, Convert.ToDouble(x.TaskDBA) / 10.0))), 1);
    }

}
codetime
  • 209
  • 2
  • 9
  • the Essentials e-mail function is not intended for sending richly formatted data in the body. You might be able to make it work, but I wouldn't recommend it. You would have better luck creating a document and adding it as an attachment, or using an external e-mail service – Jason Aug 03 '20 at 20:44
  • I wouldn't care if it's not rich, i just want to get the data from it. Also, do you have any good recommendation to create a document like you said ? – codetime Aug 03 '20 at 20:50
  • 2
    use a PDF library to build a PDF. Or just build up a string containing your data and pass it as the body of the e-mail – Jason Aug 03 '20 at 20:52

1 Answers1

1

You can convert the data of ListView to Json string , then can send them as the body of the email.

Such as follow code to convert ObservableCollection<Tasks> to Json string:

using Newtonsoft.Json;  

ResultPageViewModel pageViewModel = new ResultPageViewModel();
string output = JsonConvert.SerializeObject(pageViewModel.Tasks);

Now the output string can be sended as the body of the email.

Junior Jiang
  • 12,430
  • 1
  • 10
  • 30
  • Thanks for reply, i got this error https://stackoverflow.com/questions/13510204/json-net-self-referencing-loop-detected while applying the solution and fixed it with this link. Once i have the output how can i get the data and format them line by line to recreate the ListView experience ? Thanks again – codetime Aug 04 '20 at 03:44
  • i can do this : var results = JsonConvert.DeserializeObject(output); and then example : results[0].TaskDate but what if the listview items numbers are always different how to output them all without indexing and formatting them line by line Thanks :) – codetime Aug 04 '20 at 03:57
  • @codetime You also can convert `result` back to `ObservableCollection` ,Such as: `ObservableCollection deserializedProduct = JsonConvert.DeserializeObject >(output);` – Junior Jiang Aug 04 '20 at 05:39