简体   繁体   English

在 Xamarin Forms 上的 ListView 中为 ImageCell 设置图像

[英]Setting an image for an ImageCell in ListView on Xamarin Forms

I am trying to create a project on Xamarin Forms with a ListView.我正在尝试使用 ListView 在 Xamarin Forms 上创建一个项目。 Inside of my ListView I have an ImageCell.在我的 ListView 里面,我有一个 ImageCell。 When the project is being ran, it only shows the the ImageCell's text.当项目运行时,它只显示 ImageCell 的文本。 I need it to show the text, the detail, and the image.我需要它来显示文本、细节和图像。 I have coded what I thought looks correct but I can't figure out why it's not working.我已经编写了我认为看起来正确的代码,但我不知道为什么它不起作用。 My images are in my resources folder and I labeled them correctly.我的图像在我的资源文件夹中,我正确标记了它们。 The point of this project is to create an event calendar.这个项目的重点是创建一个事件日历。 The user will create an event, choose the date and time of the event, save it, and it should show up with a picture of the day of the week the event is on, the name of the event in the text portion, and the date and time of the event in the details portion.用户将创建一个事件,选择事件的日期和时间,保存它,它应该显示事件发生的星期几的图片,文本部分中的事件名称,以及详细信息部分中事件的日期和时间。 Can someone take a look at my code and see what I have done wrong?有人可以看看我的代码,看看我做错了什么吗? Here is my MainPage.XAML :这是我的MainPage.XAML

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MorganHall_CE04.MainPage">

    <StackLayout>
        <Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
            <Label Text="Code Example 4" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/>
        </Frame>
        <ListView x:Name="listView">
            <ListView.ItemTemplate>
                <DataTemplate>
                <ImageCell x:Name="imageCell" Text="" Detail="" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button x:Name="addButton" Text="ADD EVENT" HorizontalOptions="End" />
    </StackLayout>
</ContentPage>

Here is my MainPage.XAML.CS it's a lot...:这是我的MainPage.XAML.CS很多...:

    {
        private List<TaskData> taskList = new List<TaskData>();

        public MainPage()
        {
            InitializeComponent();

            addButton.Clicked += AddButton_Clicked;
            
            DataTemplate events = new DataTemplate(typeof(ImageCell));
            events.SetBinding(ImageCell.TextProperty, new Binding("Text"));
            events.SetBinding(ImageCell.DetailProperty, new Binding("Date" + "Time"));
            //SetValue to change color properties
            events.SetValue(ImageCell.TextColorProperty, Color.DarkBlue);
            events.SetValue(ImageCell.DetailColorProperty, Color.DarkMagenta);
            //SetImages ex: saveButton.ImageSource = ImageSource.FromFile("save48.png");
            string image = SetImages();
            events.SetValue(ImageCell.ImageSourceProperty, ImageSource.FromFile(image));
             

            listView.ItemTemplate = events;
            

            //Ask the listView to let us know anytime an item gets selected
            listView.ItemSelected += ListView_ItemSelected;

            MessagingCenter.Subscribe<string>(this, "ModifiedMessage", (sender) =>
            {
                this.ReloadListData();
                Debug.WriteLine(sender);
            });

            //Reload saved list items when app is opened
            this.ReloadListData();
        }

        private string SetImages()
        {
            //set string variable to hold the image source
            string picture = "";
            string day = "";
            //Check if taskList is empty
            if (taskList != null)
            {
                //loop through task list
                for (int i = 0; i < taskList.Count; i++)
                {
                    DateTime date = taskList[i].Date;
                    day = date.ToString("dddd");
                }
                
                //set images to the day of the week using a switch statement
                switch (day)
                {
                    case "Sunday":
                        picture = "sunday.png";
                        break;
                    case "Monday":
                        picture = "monday.png";
                        break;
                    case "Tuesday":
                        picture = "tuesday.png";
                        break;
                    case "Wednesday":
                        picture = "wednesday.png";
                        break;
                    case "Thursday":
                        picture = "thursday.png";
                        break;
                    case "Friday":
                        picture = "friday.png";
                        break;
                    case "Saturday":
                        picture = "saturday.png";
                        break;
                }
            }

            return picture;
        }

        private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            //Push taskEntry page with what was selected
            //Double check if what was selected is valid
            if (e.SelectedItem != null)
            {
                Navigation.PushAsync(new TaskEntryPage());
                MessagingCenter.Send<TaskData>((TaskData)e.SelectedItem, "EditItemMessage");
            }

        }

        protected override void OnAppearing()
        {
            //Leave base.OnApperearing
            base.OnAppearing();

            
        }

        private void ReloadListData()
        {
            //Tell taskList to clear
            taskList.Clear();

            //loop through all files that were generated and add to task list and set to data source for listView
            // * means "anything as long as it matches the last half of file name
            var files = Directory.EnumerateFiles(App.FolderPath, "*.CE04.txt");
            foreach (var filename in files)
            {
                //Read information from file
                using (var reader = new StreamReader(filename))
                {
                    var data = File.ReadAllLines(filename);
                    //Convert the date string to a DateTime object
                    DateTime dt = DateTime.Parse(data[1]);
                    //Convert the time string to a TimeSpan object
                    TimeSpan time = TimeSpan.Parse(data[2]);

                    //Add data to the taskList
                    taskList.Add(new TaskData
                    {
                        Filename = filename,
                        Text = data[0],
                        Date = dt,
                        Time = time

                    });
                }
            }
            listView.ItemsSource = taskList.OrderBy(d => d.Date).ToList();
        }

        private void AddButton_Clicked(object sender, EventArgs e)
        {
            Navigation.PushAsync(new TaskEntryPage
            {
                BindingContext = new TaskData()
            });
        }

And here is my TaskEntryPage.XAML.cs where the information should be getting saved and it's only saving the text it looks like:这是我的TaskEntryPage.XAML.cs信息应该被保存,它只保存它看起来像的文本:

    {
        TaskData editTask;

        public TaskEntryPage()
        {
            InitializeComponent();

            //Set pictures for 

            saveButton.ImageSource = ImageSource.FromFile("save48.png");
            deleteButton.ImageSource = ImageSource.FromFile("delete48.png");

            saveButton.Clicked += OnSaveButton_Clicked;

            deleteButton.Clicked += DeleteButton_Clicked;

            //subscribe to message from MainPage
            MessagingCenter.Subscribe<TaskData>(this, "EditItemMessage", (sender) =>
            {
                editTask = sender;
                taskEntry.Text = editTask.Text;
                datePicker.Date = editTask.Date;
                timePicker.Time = editTask.Time;
            });
        }

        protected override void OnAppearing()
        {
            //Leave base.OnAppearing
            base.OnAppearing();
        }

        async private void DeleteButton_Clicked(object sender, EventArgs e)
        {
            bool answer = await DisplayAlert("DELETE EVENT", "Are you sure you want to delete this event? This cannot be undone.", "YES", "NO");
            if (answer)
            {
                if (editTask != null)
                {
                    //Check if file already exists
                    if (File.Exists(editTask.Filename))
                    {
                        //Delete file
                        File.Delete(editTask.Filename);
                    }
                }

                MessagingCenter.Send<string>("ModifiedMessage Called from Delete", "ModifiedMessage");

                await Navigation.PopAsync();
            } 
        }

        private void OnSaveButton_Clicked(object sender, EventArgs e)
        {
            string filename = Path.Combine(App.FolderPath, $"{Path.GetRandomFileName()}.CE04.txt");
            string messageType = "New";
            messageType = "Edit";
            var binding = BindingContext as TaskData;
            binding.Date = datePicker.Date;
            binding.Time = timePicker.Time;
            //I can't figure out another way besides StreamWriter
            using (var writer = new StreamWriter(filename))
            {
                //write data to file
                writer.WriteLine(taskEntry.Text);
                writer.WriteLine(datePicker.Date);
                writer.WriteLine(timePicker.Time);
            }

            MessagingCenter.Send<string>("ModifiedMessage Called from " + messageType, "ModifiedMessage");

            Navigation.PopAsync();
        }
    }

and last not least, my TaskData.cs that holds the filename, date, and time:最后一点,我的TaskData.cs包含文件名、日期和时间:

    {
        public string Filename { get; set; }
        public string Text { get; set; }
        public DateTime Date { get; set; }
        public TimeSpan Time { get; set; }
    }

I know it's a lot but I'd really appreciate the help!我知道这很多,但我真的很感激你的帮助!

There are several problems in your code just as Jason said.正如杰森所说,您的代码中有几个问题。

I have achieved this function based on your code and it works properly.我已经根据您的代码实现了此功能,并且可以正常工作。 You can refer to the following code:可以参考以下代码:

MainPage.xaml主页.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:converters="clr-namespace:ImageCellApp.converters"
             x:Class="ImageCellApp.MainPage">

    <ContentPage.Resources>
        <ResourceDictionary>
            <converters:DateToStringConverter x:Key="dateToStringConverter"/>
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout>
        <Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
            <Label Text="Code Example 4" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/>
        </Frame>
        <ListView x:Name="listView">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ImageCell x:Name="imageCell" Text="{Binding Text}" ImageSource="{ Binding Date, Converter={StaticResource dateToStringConverter}}" >
                        <ImageCell.Detail>
                            <MultiBinding StringFormat="{}{0} {1}">
                                <Binding Path="Date" />
                                <Binding Path="Time" />
                            </MultiBinding>
                        </ImageCell.Detail>

                    </ImageCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button x:Name="addButton" Text="ADD EVENT" HorizontalOptions="End" />
    </StackLayout>

</ContentPage>

MainPage.xaml.cs主页.xaml.cs

public partial class MainPage : ContentPage
{
    private List<TaskData> taskList = new List<TaskData>();
    public MainPage()
    {
        InitializeComponent();

        this.ReloadListData();
    }

    private void ReloadListData()
    {
        //Tell taskList to clear
        taskList.Clear();

        taskList.Add(new TaskData { Filename = "fileName1", Text = "text1", Date = new DateTime(2021,7,19) , Time= new TimeSpan(1,20,30) });
        taskList.Add(new TaskData { Filename = "fileName2", Text = "text2", Date = new DateTime(2021, 7, 18), Time = new TimeSpan(2, 10, 30) });
        taskList.Add(new TaskData { Filename = "fileName3", Text = "text3", Date = new DateTime(2021, 7, 16), Time = new TimeSpan(1, 9, 30) });
        taskList.Add(new TaskData { Filename = "fileName4", Text = "text4", Date = new DateTime(2021, 7, 16), Time = new TimeSpan(1, 8, 30) });
        taskList.Add(new TaskData { Filename = "fileName5", Text = "text5", Date = new DateTime(2021, 7, 15), Time = new TimeSpan(1, 7, 30) });
        taskList.Add(new TaskData { Filename = "fileName6", Text = "text6", Date = new DateTime(2021, 7, 12), Time = new TimeSpan(1, 6, 30) });

        listView.ItemsSource = taskList;
    }
}

class DateToStringConverter.csDateToStringConverter.cs

public class DateToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {

        DateTime date = (DateTime)value;

        string picture = "";
        string day = "";
        day = date.ToString("dddd");

        System.Diagnostics.Debug.WriteLine("------------> day = " + day);

        //set images to the day of the week using a switch statement
        switch (day)
        {
            case "Sunday":
                picture = "sunday.png";
                break;
            case "Monday":
                picture = "monday.png";
                break;
            case "Tuesday":
                picture = "tuesday.png";
                break;
            case "Wednesday":
                picture = "wednesday.png";
                break;
            case "Thursday":
                picture = "thursday.png";
                break;
            case "Friday":
                picture = "friday.png";
                break;
            case "Saturday":
                picture = "saturday.png";
                break;
        }
        return picture;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

The result is:结果是:

在此处输入图片说明

Note:笔记:

1.You have mixed up XAML and code for your page, we usually perfer to use XAML to achieve our page; 1.你把页面的XAML和代码搞混了,我们通常更喜欢用XAML来实现我们的页面;

2.If you want to bind several fields to one view, you can use MultiBinding to achieve this, so you can use following code: 2.如果要将多个字段绑定到一个视图,可以使用MultiBinding来实现,因此可以使用以下代码:

                        <ImageCell.Detail>
                        <MultiBinding StringFormat="{}{0} {1}">
                            <Binding Path="Date" />
                            <Binding Path="Time" />
                        </MultiBinding>
                    </ImageCell.Detail>

3.If you want to display image based on field public DateTime Date { get; set; } 3.如果要根据字段显示图像public DateTime Date { get; set; } public DateTime Date { get; set; } public DateTime Date { get; set; } , you can use IValueConverter to achieve this. public DateTime Date { get; set; } ,你可以使用的IValueConverter实现这一目标。

public class DateToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {

        DateTime date = (DateTime)value;

        string picture = "";
        string day = "";
        day = date.ToString("dddd");

        System.Diagnostics.Debug.WriteLine("------------> day = " + day);

        //set images to the day of the week using a switch statement
        switch (day)
        {
            case "Sunday":
                picture = "sunday.png";
                break;
            case "Monday":
                picture = "monday.png";
                break;
            case "Tuesday":
                picture = "tuesday.png";
                break;
            case "Wednesday":
                picture = "wednesday.png";
                break;
            case "Thursday":
                picture = "thursday.png";
                break;
            case "Friday":
                picture = "friday.png";
                break;
            case "Saturday":
                picture = "saturday.png";
                break;
        }
        return picture;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM