From 17fdde66d94155fc62a034fa6658995bef6fd6e5 Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Tue, 22 Mar 2016 13:02:25 -0700 Subject: Initial import --- .../AddingMultipleItemsListView.cs | 443 +++++++++++++++++++++ 1 file changed, 443 insertions(+) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/AddingMultipleItemsListView.cs (limited to 'Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/AddingMultipleItemsListView.cs') diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/AddingMultipleItemsListView.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/AddingMultipleItemsListView.cs new file mode 100644 index 00000000..1dbd3ada --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/AddingMultipleItemsListView.cs @@ -0,0 +1,443 @@ +using System; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Diagnostics; +using System.Windows.Input; + +using Xamarin.Forms; +using Xamarin.Forms.CustomAttributes; + +#if UITEST +using NUnit.Framework; +using Xamarin.UITest; +#endif + +namespace Xamarin.Forms.Controls +{ + + public class PropertyChangedBase : INotifyPropertyChanged + { + Dictionary _properties = new Dictionary(); + + protected T GetProperty([CallerMemberName] string name = null) + { + object value = null; + if (_properties.TryGetValue(name, out value)) { + return value == null ? default(T) : (T)value; + } + return default(T); + } + + protected void SetProperty(T value, [CallerMemberName] string name = null) + { + if (Equals(value, GetProperty(name))) { + return; + } + _properties[name] = value; + OnPropertyChanged(name); + } + + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) { + handler(this, new PropertyChangedEventArgs(propertyName)); + } + } + } + + public class ViewModelError + { + public ViewModelError(string text) + { + Text = text; + } + + public string Text { get; set; } + + public override bool Equals(object obj) + { + var error = obj as ViewModelError; + if (error == null) { + return false; + } + return Text.Equals(error.Text); + } + + public override int GetHashCode() + { + return Text.GetHashCode(); + } + + public override string ToString() + { + return string.Format("ViewModelError: {0}", Text); + } + } + + public class ViewModelBase : PropertyChangedBase + { + public ViewModelBase() + { + _errors = new List(); + Validate(); + } + + readonly List _errors; + + public virtual bool IsValid + { + get { return _errors.Count <= 0; } + } + + protected IEnumerable Errors + { + get { return _errors; } + } + + public event EventHandler IsValidChanged; + + public event EventHandler IsBusyChanged; + + protected virtual void Validate() + { + OnPropertyChanged("IsValid"); + OnPropertyChanged("Errors"); + + var callback = IsValidChanged; + if (callback != null) { + callback(this, EventArgs.Empty); + } + + // Spit out errors for easier debugging. + if (_errors != null && _errors.Count > 0) { + Debug.WriteLine("Errors:"); + foreach (var error in _errors) { + Debug.WriteLine(error); + } + } + } + + protected virtual void ValidateProperty(Func validate, ViewModelError error) + { + if (validate()) { + _errors.Remove(error); + } else if (!_errors.Contains(error)) { + _errors.Add(error); + } + } + + public virtual bool IsBusy + { + get { return _isBusy; } + set + { + if (_isBusy != value) { + _isBusy = value; + OnPropertyChanged("IsBusy"); + OnIsBusyChanged(); + } + } + } + + bool _isBusy = false; + + protected virtual void OnIsBusyChanged() + { + // Some models might want to have a validation thet depends on the busy state. + Validate(); + var method = IsBusyChanged; + if (method != null) + IsBusyChanged(this, EventArgs.Empty); + } + } + + public class DelegateCommand : ICommand + { + readonly Predicate _canExecute; + readonly Action _execute; + + public event EventHandler CanExecuteChanged; + + public DelegateCommand(Action execute) + : this(execute, null) + { + } + + public DelegateCommand(Action execute, Predicate canExecute) + { + _execute = execute; + _canExecute = canExecute; + } + + public bool CanExecute(object parameter) + { + if (_canExecute == null) { + return true; + } + + return _canExecute(parameter); + } + + public void Execute(object parameter) + { + _execute(parameter); + } + + public void RaiseCanExecuteChanged() + { + var handler = CanExecuteChanged; + if (handler != null) { + handler(this, EventArgs.Empty); + } + } + } + + [Preserve (AllMembers = true)] + public class ExampleViewModel : ViewModelBase + { + [Preserve (AllMembers = true)] + public class Job : ViewModelBase + { + + public string JobId + { + get { return GetProperty(); } + set { SetProperty(value); } + } + + public string JobName + { + get { return GetProperty(); } + set { SetProperty(value); } + } + + public double? Hours + { + get { return GetProperty(); } + set { SetProperty(value); } + } + + public bool Locked + { + get { return GetProperty(); } + set { SetProperty(value); } + } + } + + public ExampleViewModel() + { + + Jobs = new ObservableCollection() + { + new Job() { JobId = "3672", JobName = "Big Job", Hours = 2}, + new Job() { JobId = "6289", JobName = "Smaller Job", Hours = 2}, + new Job() { JobId = "3672-41", JobName = "Add On Job", Hours = 23}, + }; + } + + public ObservableCollection Jobs { get; set; } + + + public ICommand AddOneCommand + { + get + { + if (_addOneCommand == null) { + _addOneCommand = new DelegateCommand(obj => { + Jobs.Add(new Job(){JobId = "1234", JobName = "add one", Hours = 12}); + }, obj => !IsBusy); + } + return _addOneCommand; + } + } + + ICommand _addOneCommand; + + public ICommand AddTwoCommand + { + get + { + if (_addTwoCommand == null) { + _addTwoCommand = new DelegateCommand(obj => { + Jobs.Add(new Job() { JobId = "9999", JobName = "add two", Hours = 12 }); + Jobs.Add(new Job() { JobId = "8888", JobName = "add two", Hours = 12 }); + }, obj => !IsBusy); + } + return _addTwoCommand; + } + } + + ICommand _addTwoCommand; + + public void GetHours() + { + + var results = new ObservableCollection() + { + new Job() { JobId = "3672", JobName = "RADO", Hours = 2}, + new Job() { JobId = "6289", JobName = "MGA Life Cycle Flexible Test System", Hours = 2}, + + }; + + foreach (var x in results) + Jobs.Add(x); + + } + } + + public class DoubleStringConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + if (null == value || "0" == value.ToString()) + return string.Empty; + return value.ToString(); + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + double? returnValue = null; + double convertResult; + var strvalue = value as string; + if (double.TryParse(strvalue, out convertResult)) + { + returnValue = convertResult; + } + return returnValue; + } + } + + [Preserve (AllMembers = true)] + [Issue (IssueTracker.None, 0, "Adding Multiple Items to a ListView", PlatformAffected.All)] + public class AddingMultipleItemsListView : TestContentPage + { + protected override void Init () + { + Title = "Hours"; + var exampleViewModel = new ExampleViewModel(); + BindingContext = exampleViewModel; + + var listView = new ListView + { + ItemTemplate = new DataTemplate(typeof(CustomViewCell)), + HeightRequest = 400, + VerticalOptions = LayoutOptions.Start + }; + + listView.SetBinding(ListView.ItemsSourceProperty, new Binding("Jobs", BindingMode.TwoWay)); + + var addOneJobButton = new Button + { + Text = "Add One" + }; + addOneJobButton.SetBinding(Button.CommandProperty, new Binding("AddOneCommand")); + + var addTwoJobsButton = new Button + { + Text = "Add Two" + }; + addTwoJobsButton.SetBinding(Button.CommandProperty, new Binding("AddTwoCommand")); + + var layout = new StackLayout + { + Orientation = StackOrientation.Vertical, + VerticalOptions = LayoutOptions.StartAndExpand, + Spacing = 15, + Children = { + listView, + addOneJobButton, + addTwoJobsButton + } + }; + Content = layout; + } + + [Preserve (AllMembers = true)] + public class CustomViewCell : ViewCell + { + public CustomViewCell () + { + var jobId = new Label { + Font = Font.SystemFontOfSize(20), + WidthRequest = 105, + VerticalOptions = LayoutOptions.Center, + + HorizontalOptions = LayoutOptions.StartAndExpand + }; + jobId.SetBinding(Label.TextProperty, "JobId"); + + var jobName = new Label { + VerticalOptions = LayoutOptions.Center, + WidthRequest = 175, + HorizontalOptions = LayoutOptions.CenterAndExpand, + }; + jobName.SetBinding(Label.TextProperty, "JobName"); + + var hours = new Label { + WidthRequest = 45, + VerticalOptions = LayoutOptions.Center, + XAlign = TextAlignment.End, + HorizontalOptions = LayoutOptions.EndAndExpand, + + }; + hours.SetBinding(Label.TextProperty, new Binding("Hours", BindingMode.OneWay, new DoubleStringConverter())); + + var hlayout = new StackLayout { + Children = { + jobId, + jobName, + hours + }, + Orientation = StackOrientation.Horizontal, + }; + + View = hlayout; + } + } + +#if UITEST + [Test] + public void AddingMultipleListViewTests1AllElementsPresent () + { + RunningApp.WaitForElement (q => q.Marked ("Big Job")); + RunningApp.WaitForElement (q => q.Marked ("Smaller Job")); + RunningApp.WaitForElement (q => q.Marked ("Add On Job")); + RunningApp.WaitForElement (q => q.Marked ("Add One")); + RunningApp.WaitForElement (q => q.Marked ("Add Two")); + RunningApp.WaitForElement (q => q.Marked ("3672")); + RunningApp.WaitForElement (q => q.Marked ("6289")); + RunningApp.WaitForElement (q => q.Marked ("3672-41")); + RunningApp.WaitForElement (q => q.Marked ("2")); + RunningApp.WaitForElement (q => q.Marked ("2")); + RunningApp.WaitForElement (q => q.Marked ("23")); + + RunningApp.Screenshot ("All elements are present"); + } + + [Test] + public void AddingMultipleListViewTests2AddOneElementToList () + { + RunningApp.Tap (q => q.Marked ("Add One")); + + RunningApp.WaitForElement (q => q.Marked ("1234"), timeout: TimeSpan.FromSeconds (2)); + RunningApp.Screenshot ("One more element exists"); + } + + [Test] + public void AddingMultipleListViewTests3AddTwoElementToList () + { + RunningApp.Screenshot ("Click 'Add Two'"); + RunningApp.Tap (q => q.Marked ("Add Two")); + + RunningApp.WaitForElement (q => q.Marked ("9999"), timeout: TimeSpan.FromSeconds (2)); + RunningApp.WaitForElement (q => q.Marked ("8888"), timeout: TimeSpan.FromSeconds (2)); + RunningApp.Screenshot ("Two more element exist"); + } +#endif + } +} -- cgit v1.2.3