[英]I'm having trouble with Data Binding in Xamarin.forms
對於一些上下文,我試圖將我的視圖鏈接到我的視圖模型。 我的 model 中有一個 JSON 對象數組和另一個字符串。 我想在我的視圖中顯示這些對象,但是我在這樣做時遇到了麻煩。
我的 Model:
namespace Timetabler.Models
{
public partial class Timetable
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("nid")]
public long Nid { get; set; }
[JsonProperty("iid")]
public long Iid { get; set; }
[JsonProperty("lid")]
public long Lid { get; set; }
[JsonProperty("start")]
public double Start { get; set; }
[JsonProperty("dur")]
public double Dur { get; set; }
[JsonProperty("weeks")]
public string Weeks { get; set; }
[JsonProperty("day")]
public long Day { get; set; }
[JsonProperty("note", NullValueHandling = NullValueHandling.Ignore)]
public string Note { get; set; }
}
public partial struct TimetableElement
{
public long? Integer;
public string String;
public Timetable TimetableClass;
public static implicit operator TimetableElement(long Integer) => new TimetableElement { Integer = Integer };
public static implicit operator TimetableElement(string String) => new TimetableElement { String = String };
public static implicit operator TimetableElement(Timetable TimetableClass) => new TimetableElement { TimetableClass = TimetableClass };
}
public partial class Timetable
{
public static TimetableElement[][] FromJson(string json) => JsonConvert.DeserializeObject<TimetableElement[][]>(json, Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this TimetableElement[][] self) => JsonConvert.SerializeObject(self, Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
TimetableElementConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class TimetableElementConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(TimetableElement) || t == typeof(TimetableElement?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.Integer:
var integerValue = serializer.Deserialize<long>(reader);
return new TimetableElement { Integer = integerValue };
case JsonToken.String:
case JsonToken.Date:
var stringValue = serializer.Deserialize<string>(reader);
return new TimetableElement { String = stringValue };
case JsonToken.StartObject:
var objectValue = serializer.Deserialize<Timetable>(reader);
return new TimetableElement { TimetableClass = objectValue };
}
throw new Exception("Cannot unmarshal type TimetableElement");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
var value = (TimetableElement)untypedValue;
if (value.Integer != null)
{
serializer.Serialize(writer, value.Integer.Value);
return;
}
if (value.String != null)
{
serializer.Serialize(writer, value.String);
return;
}
if (value.TimetableClass != null)
{
serializer.Serialize(writer, value.TimetableClass);
return;
}
throw new Exception("Cannot marshal type TimetableElement");
}
public static readonly TimetableElementConverter Singleton = new TimetableElementConverter();
}
}
我的觀點 Model:
namespace Timetabler.ViewModels
{
class TimetableViewModel : BaseViewModel
{
// First list in JSON data
public ObservableRangeCollection<TimetableElement> Names {get;}
// Second list in JSON data
public ObservableRangeCollection<TimetableElement> TypeOfClass {get;}
// Third list in JSON data
public ObservableRangeCollection<TimetableElement> Location {get;}
// Fourth list in JSON data
public ObservableRangeCollection<TimetableElement> Courses {get;}
public Command GetCoursesCommand { get; }
public Command GetNamesCommand { get; }
public TimetableViewModel()
{
Title = "Timetable";
// First list in JSON data
Names = new ObservableRangeCollection<TimetableElement>();
// Second list in JSON data
TypeOfClass = new ObservableRangeCollection<TimetableElement>();
// Third list in JSON data
Location = new ObservableRangeCollection<TimetableElement>();
// Fourth list in JSON data
Courses = new ObservableRangeCollection<TimetableElement>();
GetCoursesCommand = new Command(async () => await GetCoursesAsync());
GetNamesCommand = new Command(async () => await GetNamesAsync());
}
async Task GetNamesAsync()
{
if (IsBusy)
{
return;
}
try
{
IsBusy = true;
var timetableElements = await DataService.GetTimetablesAsync();
var names = timetableElements[0];
Names.ReplaceRange(names);
Title = $"Courses available({Names.Count}";
}
catch (Exception ex)
{
Debug.WriteLine($"Unable to get Names: {ex.Message}");
await Application.Current.MainPage.DisplayAlert("Error!", ex.Message, "OK");
}
finally
{
IsBusy = false;
}
}
async Task GetTypeOfClassAsync()
{
if (IsBusy)
{
return;
}
try
{
IsBusy = true;
var timetableElements = await DataService.GetTimetablesAsync();
var typeOfClass = timetableElements[1];
TypeOfClass.ReplaceRange(typeOfClass);
Title = $"Courses available({TypeOfClass.Count}";
}
catch (Exception ex)
{
Debug.WriteLine($"Unable to get TypeOfClass: {ex.Message}");
await Application.Current.MainPage.DisplayAlert("Error!", ex.Message, "OK");
}
finally
{
IsBusy = false;
}
}
async Task GetLocationsAsync()
{
if (IsBusy)
{
return;
}
try
{
IsBusy = true;
var timetableElements = await DataService.GetTimetablesAsync();
var location = timetableElements[2];
Location.ReplaceRange(location);
Title = $"Courses available({Courses.Count}";
}
catch (Exception ex)
{
Debug.WriteLine($"Unable to get Location: {ex.Message}");
await Application.Current.MainPage.DisplayAlert("Error!", ex.Message, "OK");
}
finally
{
IsBusy = false;
}
}
async Task GetCoursesAsync()
{
if (IsBusy)
{
return;
}
try
{
IsBusy = true;
var timetableElements = await DataService.GetTimetablesAsync();
var courses = timetableElements[3];
Courses.ReplaceRange(courses);
Title = $"Courses available({Courses.Count}";
}
catch (Exception ex)
{
Debug.WriteLine($"Unable to get courses: {ex.Message}");
await Application.Current.MainPage.DisplayAlert("Error!", ex.Message, "OK");
}
finally
{
IsBusy = false;
}
}
}
}
我的 model 將 JSON 反序列化為 C# 對象,此時我的 ViewModel 將它們分解為 ZA3CBC5Z4.166
我想在視圖中顯示這些對象。 該視圖是一個 Syncfusion 時間表。 但在這一點上,我很高興能夠在列表視圖中顯示這些對象。 我似乎也無法解決這個問題。 我努力了:
我的觀點
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:button="clr-namespace:Syncfusion.XForms.Buttons;assembly=Syncfusion.Buttons.XForms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:schedule="clr-namespace:Syncfusion.SfSchedule.XForms;assembly=Syncfusion.SfSchedule.XForms"
xmlns:viewmodel="clr-namespace:Timetabler.ViewModels"
mc:Ignorable="d"
Title="{Binding Title}"
x:Class="Timetabler.Views.TimetablePage">
<ContentPage.BindingContext>
<viewmodel:TimetableViewModel/>
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add Course" Clicked="AddItem_Clicked" />
</ContentPage.ToolbarItems>
<schedule:SfSchedule x:Name="schedule"
ScheduleView ="WorkWeekView"
TimeIntervalHeight="130"
ShowCurrentTimeIndicator="True"
DataSource="{Binding Courses}">
<schedule:SfSchedule.ViewHeaderStyle>
<schedule:ViewHeaderStyle
BackgroundColor="#FFFFFF"
CurrentDayTextColor="#d1d119"
CurrentDateTextColor="#d1d119"
DayTextColor="#44453e"
DateTextColor="#44453e"
DayFontFamily="Arial"
DateFontFamily="Arial">
</schedule:ViewHeaderStyle>
</schedule:SfSchedule.ViewHeaderStyle>
</schedule:SfSchedule>
如您所見,我正在嘗試綁定到我的 ViewModel 中的 Courses 屬性。 難道我做錯了什么? 我添加了 ContentPage。 BindingContext 作為正確的 ViewModel。 我如何能夠從其中訪問單個值?
據我所知,綁定沒問題,但您使用的是自定義 object。 您不能指望SfScheduler
知道數據需要來自哪些字段。
如此處所述,您需要告訴它要在 object 中查找哪些字段,以確定開始和結束日期和時間等屬性。 IE
<syncfusion:SfSchedule x:Name="schedule">
<syncfusion:SfSchedule.AppointmentMapping>
<syncfusion:ScheduleAppointmentMapping
ColorMapping="color"
EndTimeMapping="To"
StartTimeMapping="From"
SubjectMapping="EventName"
IsAllDayMapping="AllDay"/>
</syncfusion:SfSchedule.AppointmentMapping>
</syncfusion:SfSchedule>
查看您的TimetableElement
object 您將需要在其中添加更多屬性,因為我很確定StartTimeMapping
和EndTimeMapping
期望DateTime
。 但我可能錯了。
希望這能讓你走上正確的道路。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.