Mvvmcross MvxSimpleTableViewSource Binding - binding

I'm trying to create custom cells for my MvxTableViewController as showed in Stuart Lodge videos N=3 & N=6.5 but it fails to bind data.
Here the working version (the one with basic cells)
using Cirrious.MvvmCross.Binding.BindingContext;
using Cirrious.MvvmCross.Binding.Touch.Views;
using Cirrious.MvvmCross.Touch.Views;
using Cirrious.MvvmCross.ViewModels;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using Next.Client.Application.Core.Entities.Observations;
using Next.Client.Application.Core.ViewModels;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Next.Client.Application.iOS.Views
{
[Register("ObsSearchView")]
public partial class ObsSearchView : MvxTableViewController
{
public static readonly NSString CellIdentifier = new NSString("ObservationCell");
public ObsSearchView()
{
}
public ObsSearchView(IntPtr handle)
: base(handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
Request = new MvxViewModelRequest<ObsSearchViewModel>(null, null, new MvxRequestedBy());
LoadData();
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
Title = NSBundle.MainBundle.LocalizedString("Liste Observations", "Liste Observations");
}
public override void ViewWillDisappear(bool animated)
{
Title = NSBundle.MainBundle.LocalizedString("Back", "Liste Observations");
base.ViewDidDisappear(animated);
}
public void LoadData()
{
var source = new MvxStandardTableViewSource(
TableView,
UITableViewCellStyle.Subtitle,
CellIdentifier,
"TitleText BrutText; DetailText DateTimeHuman",
UITableViewCellAccessory.DisclosureIndicator
);
TableView.Source = source;
var set = this.CreateBindingSet<ObsSearchView, Core.ViewModels.ObsSearchViewModel>();
set.Bind(source).To(vm => vm.Observations);
set.Bind(source).For(s => s.SelectionChangedCommand).To(vm => vm.SelectedObsCommand);
set.Apply();
TableView.ReloadData();
}
}
}
and here the modified version to add custom cells:
using Cirrious.MvvmCross.Binding.BindingContext;
using Cirrious.MvvmCross.Binding.Touch.Views;
using Cirrious.MvvmCross.Touch.Views;
using Cirrious.MvvmCross.ViewModels;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using Next.Client.Application.Core.Entities.Observations;
using Next.Client.Application.Core.ViewModels;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Next.Client.Application.iOS.Views
{
[Register("ObsSearchView")]
public partial class ObsSearchView : MvxTableViewController
{
public static readonly NSString CellIdentifier = new NSString("ObservationCell");
public ObsSearchView()
{
}
public ObsSearchView(IntPtr handle)
: base(handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
Request = new MvxViewModelRequest<ObsSearchViewModel>(null, null, new MvxRequestedBy());
LoadData();
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
Title = NSBundle.MainBundle.LocalizedString("Liste Observations", "Liste Observations");
}
public override void ViewWillDisappear(bool animated)
{
Title = NSBundle.MainBundle.LocalizedString("Back", "Liste Observations");
base.ViewDidDisappear(animated);
}
public void LoadData()
{
var source = new MvxSimpleTableViewSource(
TableView,
ObservationCell.Key,
ObservationCell.Key
);
TableView.Source = source;
TableView.ReloadData();
}
}
}
with the custom cell class
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using Cirrious.MvvmCross.Binding.Touch.Views;
using Cirrious.MvvmCross.Binding.BindingContext;
using Next.Client.Application.Core.ViewModels;
using Next.Client.Application.Core.Entities.Observations;
namespace Next.Client.Application.iOS
{
public partial class ObservationCell : MvxTableViewCell
{
public static readonly UINib Nib = UINib.FromName ("ObservationCell", NSBundle.MainBundle);
public static readonly NSString Key = new NSString ("ObservationCell");
public ObservationCell (IntPtr handle) : base (handle)
{
this.DelayBind(() => {
var set = this.CreateBindingSet<ObservationCell, Observation>();
set.Bind(MainLbl).To(observation => observation.BrutText);
set.Bind(SubLeftLbl).To(observation => observation.DateTimeHuman);
set.Bind(SubRightLbl).To(observation => observation.Praticien.Personne.DisplayFullName);
set.Apply();
});
}
public static ObservationCell Create ()
{
return (ObservationCell)Nib.Instantiate (null, null) [0];
}
}
}
and finally the Observation entity
using Next.Client.Application.Core.Helpers;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Next.Client.Application.Core.Entities;
using System.Globalization;
namespace Next.Client.Application.Core.Entities.Observations
{
public class Observation : Entity
{
#region Constructors
#endregion
#region Constantes
private readonly List<String> _month = new List<String>{
"",
"jan.",
"fev.",
"mars",
"avr.",
"mai",
"juin",
"jui.",
"aout",
"sep.",
"oct.",
"nov.",
"dec."
};
#endregion
#region Simple Properties
#region Foreign keys
private int _praticienId;
public int PraticienId
{
get { return _praticienId; }
set { _praticienId = value; OnPropertyChange(() => PraticienId); }
}
private int _sejourId;
public int SejourId
{
get { return _sejourId; }
set { _sejourId = value; OnPropertyChange(() => SejourId); }
}
private int _categoryId;
public int CategoryId
{
get { return _categoryId; }
set { _categoryId = value; OnPropertyChange(() => CategoryId); }
}
#endregion
private DateTime _dateTime;
public DateTime DateTime
{
get { return _dateTime; }
set { _dateTime = value; OnPropertyChange(() => DateTime); OnPropertyChange(() => DateTimeHuman); }
}
public String DateTimeHuman
{
get
{
CultureInfo culture = new CultureInfo("fr-FR");
return DateTime.ToString("f", culture);
}
}
public string DisplayDateTime
{
get { return string.Format("{0} {1} {2} {3}h{4:00}", _dateTime.Day, _month[_dateTime.Month], _dateTime.Year, _dateTime.Hour, _dateTime.Minute); }
}
private int _status;
public int Status
{
get { return _status; }
set { _status = value; OnPropertyChange(() => Status); }
}
private int _type;
public int Type
{
get { return _type; }
set { _type = value; OnPropertyChange(() => Type); }
}
private bool _private;
public bool Private
{
get { return _private; }
set { _private = value; OnPropertyChange(() => Private); OnPropertyChange(() => DisplayPrivacy); }
}
public string DisplayPrivacy
{
get { if (_private) return "OUI"; else return "NON"; }
}
private string _brutText;
public string BrutText
{
get { return _brutText; }
set { _brutText = value; OnPropertyChange(() => BrutText); }
}
#endregion
#region Navigation Properties
private Praticien _praticien;
public Praticien Praticien
{
get { return _praticien; }
set
{
Praticien old = _praticien;
_praticien = value;
CollectionHelper.ManyToOne(this, old, value, _GetManyToOneCollection);
OnPropertyChange(() => Praticien);
}
}
private Sejour _sejour;
public Sejour Sejour
{
get { return _sejour; }
set
{
Sejour old = _sejour;
_sejour = value;
CollectionHelper.ManyToOne(this, old, value, _GetManyToOneCollection);
OnPropertyChange(() => Sejour);
}
}
private Category _category;
public Category Category
{
get { return _category; }
set
{
Category old = _category;
_category = value;
CollectionHelper.ManyToOne(this, old, value, _GetManyToOneCollection);
OnPropertyChange(() => Category);
}
}
private ObservableCollection<BinaryObservation> _datas;
public ObservableCollection<BinaryObservation> Datas
{
get
{
if (_datas == null)
{
_datas = new ObservableCollection<BinaryObservation>();
CollectionHelper.OneToMany(this, _GetOneToMany, _SetOneToMany, _datas);
}
return _datas;
}
set { _datas = value; OnPropertyChange(() => Datas); }
}
#endregion
#region Association Fixup
private static ObservableCollection<Observation> _GetManyToOneCollection(Sejour sejour)
{
return sejour.Observations;
}
private static ObservableCollection<Observation> _GetManyToOneCollection(Category category)
{
return category.Observations;
}
private static ObservableCollection<Observation> _GetManyToOneCollection(Praticien praticien)
{
return praticien.Observations;
}
#region binary observation (datas)
private static Observation _GetOneToMany(BinaryObservation binaryObservation)
{
return binaryObservation.Observation;
}
private static void _SetOneToMany(BinaryObservation binaryObservation, Observation observation)
{
binaryObservation.Observation = observation;
}
#endregion
#endregion
}
}
when I build I get no error and I can run the debugger without errors either, but when using the custom cells nothing show up, so it seems the binding isn't done the right way.
Thanks for your time

In your modified ObsView you are never actually binding the ItemsSource for TableSource - so the table source doesn't know what collection to show
In the N+1 3 Kittens tutorial this is done using:
var set = this.CreateBindingSet<FirstView, FirstViewModel>();
set.Bind(source).To(vm => vm.Kittens);
set.Apply();
See https://github.com/MvvmCross/NPlus1DaysOfMvvmCross/blob/master/N-03-KittenView_Mac/KittenView.Touch/Views/FirstView.cs#L24
Similarly, in N=6:
var set = this.CreateBindingSet<FirstView, Core.ViewModels.FirstViewModel>();
// ...
set.Bind(source).To(vm => vm.Results);
// ...
set.Apply();
See https://github.com/MvvmCross/NPlus1DaysOfMvvmCross/blob/master/N-07-BooksPlus/Books.Touch/Views/FirstView.cs#L45

Related

Filter ListView with SearchView xamarin

I want to filter Listview by Searchview
I use the following Adapter for the filter and it works if I haven't made any new additions to the adapter
When I add a new item to Listview, the search stops completely until I restart the program after adding, modifying or deleting it
full code
adapter class
Do you want to achieve the result like following GIF?
If you want to add the item to the listview, based on your adapter, you should item in the adapter like following code.
public class TableItemAdapter : BaseAdapter<TableItem>, IFilterable
{
public List<TableItem> _originalData;
public List<TableItem> _items;
private readonly Activity _context;
public TableItemAdapter(Activity activity, IEnumerable<TableItem> tableitems)
{
_items = tableitems.ToList();
_context = activity;
Filter = new TableItemFilter(this);
}
//Add data to the `_items`, listview will be updated, if add data in the activity,
//there are two different lists, so listview will not update.
public void AddData(TableItem tableItem)
{
_items.Add(tableItem);
NotifyDataSetChanged();
}
public override TableItem this[int position]
{
get { return _items[position]; }
}
public Filter Filter { get; private set; }
public override int Count
{
get { return _items.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = _items[position];
View view = convertView;
if (view == null) // no view to re-use, create new
view = convertView ?? _context.LayoutInflater.Inflate(Resource.Layout.TableItem, null);
//view = _context.LayoutInflater.Inflate(Resource.Layout.TableItem, null);
view.FindViewById<TextView>(Resource.Id.Text1).Text = item.Heading;
view.FindViewById<TextView>(Resource.Id.Text2).Text = item.SubHeading;
return view;
}
public override void NotifyDataSetChanged()
{
// this.NotifyDataSetChanged();
base.NotifyDataSetChanged();
}
}
public class TableItemFilter :Filter
{
private readonly TableItemAdapter _adapter;
public TableItemFilter(TableItemAdapter adapter)
{
_adapter = adapter;
}
protected override FilterResults PerformFiltering(ICharSequence constraint)
{
var returnObj = new FilterResults();
var results = new List<TableItem>();
if (_adapter._originalData == null)
_adapter._originalData = _adapter._items;
if (constraint == null) return returnObj;
if (_adapter._originalData != null && _adapter._originalData.Any())
{
results.AddRange(
_adapter._originalData.Where(
item => item.SubHeading.ToLower().Contains(constraint.ToString()) | item.Heading.ToLower().Contains(constraint.ToString())));
}
returnObj.Values = FromArray(results.Select(r => r.ToJavaObject()).ToArray());
returnObj.Count = results.Count;
constraint.Dispose();
return returnObj;
}
protected override void PublishResults(ICharSequence constraint, FilterResults results)
{
using (var values = results.Values)
_adapter._items = values.ToArray<Java.Lang.Object>().Select(r => r.ToNetObject<TableItem>()).ToList();
_adapter.NotifyDataSetChanged();
// Don't do this and see GREF counts rising
constraint.Dispose();
results.Dispose();
}
}
public class JavaHolder : Java.Lang.Object
{
public readonly object Instance;
public JavaHolder(object instance)
{
Instance = instance;
}
}
public static class ObjectExtensions
{
public static TObject ToNetObject<TObject>(this Java.Lang.Object value)
{
if (value == null)
return default(TObject);
if (!(value is JavaHolder))
throw new InvalidOperationException("Unable to convert to .NET object. Only Java.Lang.Object created with .ToJavaObject() can be converted.");
TObject returnVal;
try { returnVal = (TObject)((JavaHolder)value).Instance; }
finally { value.Dispose(); }
return returnVal;
}
public static Java.Lang.Object ToJavaObject<TObject>(this TObject value)
{
if (Equals(value, default(TObject)) && !typeof(TObject).IsValueType)
return null;
var holder = new JavaHolder(value);
return holder;
}
}
}
Then in the activity, you add the data by adapter.
private void Button1_Click(object sender, System.EventArgs e)
{
tableItemAdapter.AddData(new TableItem() { Heading = "test1222", SubHeading = "sub Test" });
}
Here is my demo, you can download it.
https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/XAListViewSearchDemo.zip

Listview Filter with SearchView Using Base Adapter in Xamarin android Error

I am try to filter listview with searchview using Base Adapter in in xamarin Android, My listView Bind in sql server using restfull web service i am stuck in PublishResults which is given an error
Here Is My Code:-
GetHospNames.cs
public class GetHospNames
{
public string HospID { get; set; }
public string HospName { get; set; }
public GetHospNames(string HospID, string HospName)
{
this.HospID = HospID;
this.HospName = HospName;
//this.HospLogo = HospLogo;
}
}
ContListViewHospNameClass.cs
using System.Collections.Generic;
using Android.App;
using Android.Views;
using Android.Widget;
using System;
using Android.Graphics;
using Android.Graphics.Drawables;
using System.IO;
using Android.Content;
using Java.Lang;
using Android.Text;
using Java.Util;
using Oject = Java.Lang.Object;
namespace HSAPP
{
public class ContListViewHospNameClass : BaseAdapter<GetHospNames>, IFilterable
{
public List<GetHospNames> objList;
Activity objActivity;
List<GetHospNames> filterList;
public ContListViewHospNameClass(Activity objMyAct, List<GetHospNames> objMyList) : base()
{
this.objActivity = objMyAct;
objList = objMyList;
this.filterList = objList;
Filter = new CustomFilter(this);
}
public override GetHospNames this[int position]
{
get
{
return objList[position];
}
}
public override int Count
{
get
{
return objList.Count;
}
}
public Filter Filter { get; set; }
public override void NotifyDataSetChanged()
{
base.NotifyDataSetChanged();
}
//This is Inner Class
public class CustomFilter : Filter
{
ContListViewHospNameClass CustomAdapter;
public CustomFilter(ContListViewHospNameClass adapter) : base()
{
this.CustomAdapter = adapter;
}
protected override FilterResults PerformFiltering(ICharSequence constraint)
{
FilterResults result = new FilterResults();
if (constraint != null && constraint.Length() > 0)
{
//Contraint To Upper
List<GetHospNames> filter = new List<GetHospNames>();
foreach (GetHospNames name in CustomAdapter.objList)
{
if (name.HospName.ToUpper().Contains(constraint.ToString().ToUpper()))
{
filter.Add(name);
}
}
Oject[] Name;
Name = new Oject[filter.Count];
for (int i = 0; i < filter.Count; i++)
{
Name[i] = filter[i].HospName.ToString();
}
result.Count = filter.Count;
result.Values = Name;
}
return result;
}
protected override void PublishResults(ICharSequence constraint, Filter.FilterResults result)
{
List<GetHospNames> filteredList = new List<GetHospNames>();
for (int i = 0; i < ((Oject[])result.Values).Length; i++)
{
filteredList.Add((Oject[])result.Values[i]);//Here Is An Error *****Cannot apply indexing with [] to an expression of type 'Object'****
}
CustomAdapter.objList = filteredList;
CustomAdapter.NotifyDataSetChanged();
}
}
public override long GetItemId(int position)
{
return position;
}
public Bitmap getBitmap(byte[] getByte)
{
if (getByte.Length != 0)
{
return BitmapFactory.DecodeByteArray(getByte, 0, getByte.Length);
}
else
{
return null;
}
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = objList[position];
if (convertView == null)
{
convertView = objActivity.LayoutInflater.Inflate(Resource.Layout.ContListViewHospName, null);
}
convertView.FindViewById<TextView>(Resource.Id.tvHospID).Text = item.HospID;
convertView.FindViewById<TextView>(Resource.Id.tvHospName).Text = item.HospName;
return convertView;
}
}
public static class ObjectTypeHelper
{
public static T Cast<T>(this Java.Lang.Object obj) where T : class
{
var propertyInfo = obj.GetType().GetProperty("Instance");
return propertyInfo == null ? null : propertyInfo.GetValue(obj, null) as T;
}
}
}
This is my MainActivity Code
private void BindControl_BindHospCompleted(object sender, BindControl.BindHospCompletedEventArgs e)
{
jsonValue = e.Result.ToString();
try
{
if (jsonValue == null)
{
Toast.MakeText(this, "No Data For Bind", ToastLength.Long).Show();
return;
}
JArrayValue = JArray.Parse(jsonValue);
list = new List<GetHospNames>();
int count = 0;
while (count < JArrayValue.Count)
{
GetHospNames getHospName = new GetHospNames(JArrayValue[count]["HospID"].ToString(), JArrayValue[count]["HospName"].ToString());
list.Add(getHospName);
count++;
}
if (count == 0)
{
Toast.MakeText(this, "No List Of Hospitals", ToastLength.Long).Show();
}
adapter = new ContListViewHospNameClass(this, list);
listView.Adapter = adapter;
search.QueryTextChange += (s, e) =>
{
adapter.Filter.InvokeFilter(e.NewText);
};
listView.ItemClick += ListView_ItemClick;
pBar.Dismiss();
}
catch (Java.Lang.Exception ex)
{
pBar.Dismiss();
//Toast.MakeText(this, ex.ToString(), ToastLength.Long).Show();
Finish();
Intent intent = new Intent(this, typeof(ChkIntConnActivity));
StartActivity(intent);
}
}
Please Help...Thank You

Castle.Windsor - How to implement TypedFactoryFacility

Recently, I developed a component , using factory pattern. However, I did a research. on how to improve it using TypedFactoryFacility, since we are using Castle.WIndsor.
Can you please provide a simple complete example? I have read few of them but still can't really fully understand . SO far, my code looks like that :
public class DynamoStoreService : IDynamoStoreService
{
private IDynamoStoreFactory _dynamoStoreFactory;
public DynamoStoreService(IDynamoStoreFactory dynamoStoreFactory)
{
_dynamoStoreFactory=dynamoStoreFactory;
}
public IDynamoStore GetProductDataDynamoStore(string storageAccount)
{
return _dynamoStoreFactory.Create(storageAccount);
}
}
public class DynamoStoreFactory : IDynamoStoreFactory
{
private IStorageAccountSelector _storageAccountSelector;
public DynamoStoreFactory(IStorageAccountSelector storageAccountSelector)
{
_storageAccountSelector = storageAccountSelector;
}
public IDynamoStore Create(string storageAccount)
{
return new AzureKeyValueStore(_storageAccountSelector.GetCredentials(storageAccount).StorageAccount, "pointerfiles");
}
}
public class StorageAccountSelector : IStorageAccountSelector
{
private readonly IConfigurationSettings _settings;
public StorageAccountSelector(IConfigurationSettings settings)
{
_settings = settings;
}
BlobCredentials IStorageAccountSelector.GetCredentials(string storageAccount)
{
return new BlobCredentials()
{
Container = string.Empty,
StorageAccount = GetStorageAccount(storageAccount)
};
}
private string GetStorageAccount(string storageAccount)
{
switch (storageAccount)
{
case "CustomerPolarisingCategoryBlobStorageAccountKey":
return _settings.CustomerPolarisingCategoryBlobStorageAccount;
case "CustomerPolarisingSegmentBlobStorageAccountKey":
return _settings.CustomerPolarisingSegmentBlobStorageAccount;
case "P2ProductSimilarityBlobStorageAccountKey":
return _settings.P2ProductSimilarityBlobStorageAccount;
case "ProductPolarisingCategoryBlobStorageAccountKey":
return _settings.ProductPolarisingCategoryBlobStorageAccount;
case "ProductPolarisingSegmentBlobStorageAccountKey":
return _settings.ProductPolarisingSegmentBlobStorageAccount;
case "SignalBlobStorageAccountKey":
return _settings.SignalBlobStorageAccount;
}
return string.Empty;
}
}
}
So basically, the IDynamostore , whenvever called, we need to be able to pass a different connection string. I have figured out the above design.. could this be improved using TypedFactoryFacility?
Thanks
Maybe the code below can give you an idea about how to use the TypedFactoryFacility. If you have studied it and have questions about it, please let me know.
Kind regards,
Marwijn.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
namespace ConsoleApplication3
{
public class TypedFactoryComponentSelector : DefaultTypedFactoryComponentSelector
{
private readonly StorageAccountSelector _storageAccountSelector;
public TypedFactoryComponentSelector(StorageAccountSelector storageAccountSelector)
{
_storageAccountSelector = storageAccountSelector;
}
protected override System.Collections.IDictionary GetArguments(MethodInfo method, object[] arguments)
{
var dictionary = new Dictionary<string, object>();
dictionary.Add("mappedStorageAccount", _storageAccountSelector.GetCredentials((string)arguments[0]).StorageAccount);
dictionary.Add("files", "pointerfiles");
return dictionary;
}
}
public interface IDynamoStore
{
}
public class AzureKeyValueStore : IDynamoStore
{
public AzureKeyValueStore(string mappedStorageAccount, string files)
{
Console.WriteLine(mappedStorageAccount);
Console.WriteLine(files);
}
}
public class BlobCredentials
{
public string Container { get; set; }
public string StorageAccount { get; set; }
}
public interface IDynamoStoreFactory
{
IDynamoStore Create(string storageAccount);
}
public class StorageAccountSelector
{
public BlobCredentials GetCredentials(string storageAccount)
{
return new BlobCredentials()
{
Container = string.Empty,
StorageAccount = GetStorageAccount(storageAccount)
};
}
public string GetStorageAccount(string storageAccount)
{
return storageAccount + "Mapped";
return string.Empty;
}
}
class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<IDynamoStoreFactory>().AsFactory(new TypedFactoryComponentSelector(new StorageAccountSelector())),
Component.For<IDynamoStore>().ImplementedBy<AzureKeyValueStore>()
);
var factory = container.Resolve<IDynamoStoreFactory>();
factory.Create("storageAccount");
}
}
}

MVVMCROSS Ios Binding ShowViewModel

I've got problem with data-binding in mvvmcross after doing the navigation in the model by calling the showviewmodel-method. On the android side it works.
So the Problem is, that the navigation itself is working but I don't get any data from the model.
Navigation in the model:
ShowViewModel<TeamEventDetailsViewModel>(new { eventID = item.ID });
ViewModel which containts the Data:
public class TeamEventDetailsViewModel
: EventDetailsViewModel
{
public TeamEventModel CurrentEvent
{
get { return MyCurrentEvent as TeamEventModel; }
set
{
MyCurrentEvent = value;
RaisePropertyChanged(() => CurrentEvent);
TickerModel.Comments = value.Comments;
RaisePropertyChanged(() => TickerModel);
LineupModel.Team1Players = value.Team1Players;
LineupModel.Team2Players = value.Team2Players;
RaisePropertyChanged(() => LineupModel);
}
}
private EventDetailsLineupViewModel _lineupModel = new EventDetailsLineupViewModel();
public EventDetailsLineupViewModel LineupModel
{
get { return _lineupModel; }
set { _lineupModel = value; RaisePropertyChanged(() => LineupModel); }
}
public TeamEventDetailsViewModel()
{
EventToken = MvxMessenger.Subscribe<EventUpdateMessage>(OnEventUpdateMessage);
}
private void OnEventUpdateMessage(EventUpdateMessage eventUpdate)
{
if (MyCurrentEvent != null && eventUpdate.Event.ID == MyCurrentEvent.ID)
{
var updatedEvent = (TeamEventModel)eventUpdate.Event;
var myEvent = CurrentEvent;
if(updatedEvent.Score!=null)
myEvent.Score = updatedEvent.Score;
if (updatedEvent.Team1Players != null)
myEvent.Team1Players = updatedEvent.Team1Players;
if (updatedEvent.Team2Players != null)
myEvent.Team2Players = updatedEvent.Team2Players;
CurrentEvent = myEvent;
}
}
protected override void Update(EventModel eventdetails)
{
CurrentEvent = (TeamEventModel) eventdetails;
}
private string _teststring = "success";
public string Teststring
{
get { return _teststring; }
set
{
_teststring = value;
RaisePropertyChanged(()=>_teststring);
}
}
}
As you can see at the bottom I implemented a teststring to prove functionality.
Binding in the View:
public class TeamEventDetailsView : MvxViewController
{
public UILabel TestLabel = new UILabel();
public TeamEventDetailsViewModel TeamEventDetailsViewModel
{
get { return (TeamEventDetailsViewModel)base.ViewModel; }
set { base.ViewModel = value; }
}
public override void ViewDidLoad()
{
View.AddSubview(TestLabel);
this.CreateBinding(TestLabel).To<TeamEventDetailsViewModel>(vm => vm.Teststring).Apply();
TestLabel.BackgroundColor = UIColor.Orange;
}
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
TestLabel.Frame=new RectangleF(0,20,View.Frame.Width,80);
}
}
So I repeat, the navigation itself works but the data from model doesn't get shown on the view.
If I create the ViewModel manually in the View then the binding works also, but in my Situation I can't do that because the Data is pulled depending on the generated Data from the ViewModel which calls the navigation-proceed.
Manual ViewModel:
TeamEventDetailsViewModel = new TeamEventDetailsViewModel();
TeamEventDetailsViewModel.Init(9816);
As I can tell I did exactly the same as Stuard does in his Tutorial:
https://www.youtube.com/watch?v=cbdPDZmuHk8
Does anyone has an advice for me?
Thanks.
MvvmCross does the ViewModel create in base.ViewDidLoad() - if you add that call to your ViewDidLoad override then everything should work ok

The query results cannot be enumerated more than once, MVC WebGrid issue

Error:
System.InvalidOperationException: The query results cannot be enumerated more than once.
Code:
Controller:
namespace EmployeeAttendance_app.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Precise Technology Consultants";
var DataContext = new EmployeeAtdDataContext();
//var EmployeeAtd = DataContext.GetAttendance_Sp();
IEnumerable<GetAttendance_SpResult> EmployeeAtd = DataContext.GetAttendance_Sp();
return View(EmployeeAtd);
}
View:
#using EmployeeAttendance_app.Models
<div>
#{
var grid = new WebGrid(Model, defaultSort: "EmplID");
}
#grid.GetHtml()
</div>
Models:
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.237
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace EmployeeAttendance_app.Models
{
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Linq.Expressions;
using System.ComponentModel;
using System;
[global::System.Data.Linq.Mapping.DatabaseAttribute(Name="a1")]
public partial class EmployeeAtdDataContext : System.Data.Linq.DataContext
{
private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
#region Extensibility Method Definitions
partial void OnCreated();
#endregion
public EmployeeAtdDataContext() :
base(global::System.Configuration.ConfigurationManager.ConnectionStrings["a1ConnectionString"].ConnectionString, mappingSource)
{
OnCreated();
}
public EmployeeAtdDataContext(string connection) :
base(connection, mappingSource)
{
OnCreated();
}
public EmployeeAtdDataContext(System.Data.IDbConnection connection) :
base(connection, mappingSource)
{
OnCreated();
}
public EmployeeAtdDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
public EmployeeAtdDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
public System.Data.Linq.Table<EmployeeAtd> EmployeeAtds
{
get
{
return this.GetTable<EmployeeAtd>();
}
}
[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.GetAttendance_Sp")]
public ISingleResult<GetAttendance_SpResult> GetAttendance_Sp()
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
return ((ISingleResult<GetAttendance_SpResult>)(result.ReturnValue));
}
}
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.V_EmployeeAtd")]
public partial class EmployeeAtd
{
private string _EmplID;
private string _EmplName;
private string _RecDate;
private string _RecTime;
private string _DeptName;
public EmployeeAtd()
{
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmplID", DbType="Char(8) NOT NULL", CanBeNull=false)]
public string EmplID
{
get
{
return this._EmplID;
}
set
{
if ((this._EmplID != value))
{
this._EmplID = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmplName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
public string EmplName
{
get
{
return this._EmplName;
}
set
{
if ((this._EmplName != value))
{
this._EmplName = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RecDate", DbType="Char(10)")]
public string RecDate
{
get
{
return this._RecDate;
}
set
{
if ((this._RecDate != value))
{
this._RecDate = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RecTime", DbType="Char(5)")]
public string RecTime
{
get
{
return this._RecTime;
}
set
{
if ((this._RecTime != value))
{
this._RecTime = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_DeptName", DbType="NVarChar(50)")]
public string DeptName
{
get
{
return this._DeptName;
}
set
{
if ((this._DeptName != value))
{
this._DeptName = value;
}
}
}
}
public partial class GetAttendance_SpResult
{
private string _EmplID;
private string _EmplName;
private string _RecDate;
private string _RecTime;
private string _DeptName;
public GetAttendance_SpResult()
{
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmplID", DbType="Char(8) NOT NULL", CanBeNull=false)]
public string EmplID
{
get
{
return this._EmplID;
}
set
{
if ((this._EmplID != value))
{
this._EmplID = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_EmplName", DbType="NVarChar(40) NOT NULL", CanBeNull=false)]
public string EmplName
{
get
{
return this._EmplName;
}
set
{
if ((this._EmplName != value))
{
this._EmplName = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RecDate", DbType="Char(10)")]
public string RecDate
{
get
{
return this._RecDate;
}
set
{
if ((this._RecDate != value))
{
this._RecDate = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RecTime", DbType="Char(5)")]
public string RecTime
{
get
{
return this._RecTime;
}
set
{
if ((this._RecTime != value))
{
this._RecTime = value;
}
}
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_DeptName", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
public string DeptName
{
get
{
return this._DeptName;
}
set
{
if ((this._DeptName != value))
{
this._DeptName = value;
}
}
}
}
}
#pragma warning restore 1591
I'm newbie to MVC 3 and Linq to SQL, trying to display data in GRID using WebGrid class but getting error. I have used Linq to Sql class and dropped SP and table into it.
Change you View to accept list of GetAttendance_SpResult bcoz you are passing this model from your controller
#model IEnumerable<GetAttendance_SpResult>
Try converting ur IEnumerable to List. because When you use .ToList() on IEnumerable, all the items in the IEnumerable saved as a List. and when u work with IEnumerable item is accessed from your database
#{
var grid = new WebGrid(Model.ToList(), defaultSort: "EmplID");
}
#grid.GetHtml()

Resources