【发布时间】:2021-07-19 01:07:13
【问题描述】:
我正在尝试使用 ListView 在 Xamarin Forms 上创建一个项目。在我的 ListView 里面我有一个 ImageCell。当项目正在运行时,它只显示 ImageCell 的文本。我需要它来显示文本、细节和图像。我已经编写了我认为正确的代码,但我不知道为什么它不起作用。我的图像在我的资源文件夹中,并且我正确标记了它们。这个项目的重点是创建一个事件日历。用户将创建一个事件,选择事件的日期和时间,保存它,它应该显示事件发生的星期几的图片,文本部分中的事件名称,以及详细信息部分中事件的日期和时间。有人可以看看我的代码,看看我做错了什么吗?
这是我的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>
这是我的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()
});
}
这是我的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();
}
}
最后同样重要的是,我的TaskData.cs 保存了文件名、日期和时间:
{
public string Filename { get; set; }
public string Text { get; set; }
public DateTime Date { get; set; }
public TimeSpan Time { get; set; }
}
我知道这很多,但我非常感谢您的帮助!
【问题讨论】:
-
哪里有很多错误。首先,您为什么要在 XAML 和代码中创建模板?选择其中一个(通常首选 XAML)。第二,
Binding("Date" + "Time")不会做你想做的事。在 XAML 中执行此操作并使用FormatString会简单得多。第三,SetImages()没有做任何有用的事情。您可以通过使用IValueConverter将Date转换为用作图像源的字符串来大大简化此操作。
标签: c# android xamarin xamarin.forms