How to Bind Button Inside Collection View Cell in MVVMCross Xamarin.iOS? - xamarin.ios

I am unable to find the solution of my problem. I want to bind a button inside a collection view cell to my View Model.e.g My view Code is
VideoQueueCollectionView.RegisterNibForCell(QueueItemCell.Nib, QueueItemCell.Key);
var source = new MvxCollectionViewSource(VideoQueueCollectionView, QueueItemCell.Key);
VideoQueueCollectionView.Source = source;
var set = this.CreateBindingSet<VideoQueueView, VideoQueueViewModel>();
set.Bind(source).To(vm => vm.VideoTrailers);
set.Bind(source).For(b => b.SelectionChangedCommand).To(vm => vm.ViewVideoTrailerCommand);
set.Apply();
And My Collection View Cell Code looki like that
public QueueItemCell (IntPtr handle) : base (handle)
{
this.DelayBind (() => {
var set = this.CreateBindingSet<QueueItemCell, DeviceQueueItem> ();
set.Bind (SourceNameLabel).To (vm => vm.SourceDeviceName);
set.Bind (ReceivedTimeLabel).To (vm => vm.ReceivedTime);
set.Bind (ButtonCross).To (????????);
set.Apply ();
SetFont();
});
}
Because My Command is in VideoQueueViewModel. How I can bind this Command. I am stuck in this issues from past 2 days
Thanks in advance.

You need to wrap your viewmodel into the row model. That way you can access the command that is on the viewmodel. This issue is also discussed in: https://github.com/MvvmCross/MvvmCross/issues/35
and: How to binding list item to whether it is contained in another collection

Related

CS1646 Keyword, identifier, or string expected after verbatim specifier: #

tables in my EntityFramework model are events, eventtypes, subevents, subeventtypes
using the MVC5 builders (right click on controllers, add, add controller) I created controllers and views for the last three tables without issue however when I create the controller and views for the events entity I produce the following errors
Keyword, identifier, or string expected after verbatim specifier: #
'EventType' is a type, which is not valid in the given context
the code that was generated in the event controller is
{
private Entities db = new Entities();
// GET: Events
public ActionResult Index()
{
var events = db.Events.Include(# => #.EventType); ERROR HERE
return View(events.ToList());
}
any help with this issue would be greatly appreciated
TIA
I experienced the same issue when using the "MVC Controller with views, using Entity Framework" template.
var #group = await _context.Groups
.Include(# => #.Company)
.FirstOrDefaultAsync(m => m.GroupId == id);
My workaround was simple to replace the # symbol with another character i.e. g
var #group = await _context.Groups
.Include(g => g.Company)
.FirstOrDefaultAsync(m => m.GroupId == id);

Dynamically added menu (PXAction + MenuAutoOpen + AddMenuAction) gets hidden in some screens, but not others

I am trying to dynamically add a menu and related actions through a graph extension. The code I have written works in some screens but not in others. I can see the menu appear during post-back but it gets hidden right away: http://recordit.co/T5KSEz7QJv
I have spent a few hours investigating the problem and here's what I found so far:
If I don't add my action to a menu, it works in every cases. The issue is only when using AddMenuAction. I see that there's some logic inside PXAction to show/hide the menu based on visibility of the items inside the menu, but I couldn't figure the problem out.
If the menu itself is directly declared in the graph extension (using public PXAction... and attributes), it works as expected. It is not an option in my case because I am trying to create a generic mechanism that will allow me to add actions to any graph type.
The two following graph extensions highlight this problem - the first one is for Sales Orders entry, and the other for Business Account maintenance. They are identical, except for the graph type parameter:
//This extension works fine, button displays as expected
public class TestButtonsSO : PXGraphExtension<SOOrderEntry>
{
public override void Initialize()
{
base.Initialize();
Type primaryViewItemType = Base.Views[Base.PrimaryView].Cache.GetItemType();
var myMenu = PXNamedAction.AddAction(Base, primaryViewItemType, "MyMenu", "My Menu",
a => a.Get(),
new PXEventSubscriberAttribute[] { new PXButtonAttribute() { MenuAutoOpen = true } });
var action = PXNamedAction.AddAction(Base, primaryViewItemType, "MyMenu$Test", "Test",
a => throw new PXException("Clicked!"),
new PXEventSubscriberAttribute[] { new PXButtonAttribute() { } });
myMenu.AddMenuAction(action);
}
}
//The menu will appear during post-back but gets hidden right away
public class TestButtonsBAccount: PXGraphExtension<BusinessAccountMaint>
{
public override void Initialize()
{
base.Initialize();
Type primaryViewItemType = Base.Views[Base.PrimaryView].Cache.GetItemType();
var myMenu = PXNamedAction.AddAction(Base, primaryViewItemType, "MyMenu", "My Menu",
a => a.Get(),
new PXEventSubscriberAttribute[] { new PXButtonAttribute() { MenuAutoOpen = true } });
var action = PXNamedAction.AddAction(Base, primaryViewItemType, "MyMenu$Test", "Test",
a => throw new PXException("Clicked!"),
new PXEventSubscriberAttribute[] { new PXButtonAttribute() { } });
myMenu.AddMenuAction(action);
}
}
Upon the investigation, this issue seems to be caused by PXGridWithPreview corrupting ToolBarItemCollection in the DataSource. Your approach above will perfectly work on all Acumatica screens, which do not contain a PXGridWithPreview control. For screens already utilizing PXGridWithPreview, we'll have to wait until a fix is realised by Acumatica Engineering Team (will keep this item on my radar and post an update once the fix is available)

How do I handle binding in UITableViewCells

I've been doing some work on an app using ReactiveUI.
My issue is with UITableViews and the reusing of cells. I tried using ReactiveTableViewSource, but that didn't seem to give me the level of customisation I wanted (custom header and footer views).
So I used UITableViewSource and UITableViewCell and implemented IViewFor.
I then did the binding in the individual cells.
That works fine, but I'm worried about "re-binding" to the new ViewModel every time a cell is reused. I believe I've worked around it, but I'm sure there's a better way to do it.
Code I'm using (only the relevant bit):
public partial class FlavourTableViewCell : UITableViewCell, IViewFor<MenuItemViewModel.FlavourSetItemViewModel>
{
public MenuItemViewModel.FlavourSetItemViewModel ViewModel { get; set; }
object IViewFor.ViewModel { get { return ViewModel; } set { ViewModel = (MenuItemViewModel.FlavourSetItemViewModel)value; } }
List<IDisposable> bindings = new List<IDisposable> ();
// Called when new data should be shown in cell
internal void Update (MenuItemViewModel.FlavourSetItemViewModel data, MenuItemViewModel.FlavourSelectionEnum type)
{
ViewModel = data;
// Clear old bindings
if (bindings.Any ()) {
bindings.ForEach (x => x.Dispose ());
bindings.Clear ();
}
bindings.Add (this.Bind (ViewModel, x => x.IsSelected, view => view.SelectionButton.Selected));
}
}
Additional info:
FlavourSetItemViewModel contains a list of FlavourSetItemViewModel. I'll try to explain below:
FlavourSetItemViewModel - Has section name
FlavourSetItemViewModel - Has item name
FlavourSetItemViewModel - Has item name
FlavourSetItemViewModel - Has item name
FlavourSetItemViewModel - Has item name
FlavourSetItemViewModel - Has section name
FlavourSetItemViewModel - Has item name
What you're doing doesn't look wrong to me. What you could improve is using a CompositeDisposable instead of a List of IDisposable.
But you could also try using ReactiveTableViewSource by using your own implementation and then overriding GetViewForHeader to supply your own header views.
You can then bind your data to your custom table view source:
this.WhenAnyValue (view => view.ViewModel.Section1, view => view.ViewModel.Section2, (section1, section2) => new TableSectionInformation<TModel> [] {
new TableSectionInformation<TModel, TReactiveTableViewCell> (section1, "section1cell", 44),
new TableSectionInformation<TModel, TReactiveTableViewCell> (section2, "section2cell", 44)
})
.BindTo (tableViewSource, x => x.Data);
If you're using a dynamic amount of sections, you could do the following:
this.WhenAnyValue (view => view.ViewModel.TableSections)
.Select (tableData => tableData.Select (section => new TableSectionInformation<TModel, TReactiveTableViewCell> (section, "cellIdentifier", 44)).ToArray ())
.BindTo (tableViewSource, x => x.Data);
Assuming TableData is an 2-dimensional list of sorts.
Take care that in my sample, changes to the list(s) are not taken into account. Only changes to the property (TableSections) itself.

Set PageSize in a Taxonomy view

I've started my first project using OrchardCMS and so far so good. It's a brilliant piece of kit and amazingly powerful once you get up to speed with the terminology of it.
One area I'm struggling with is displaying Taxonomies. There seems to be almost no documentation on it, and Shape Tracing is not being very useful.
I'm using a taxonomy to display content items that have the same term. This is all working great now, however the default pagination page size is 10 items. I've dug through lots of code and found this is driven from TermPart
protected override DriverResult Display(TermPart part, string displayType, dynamic shapeHelper) {
return Combined(
ContentShape("Parts_TermPart_Feed", () => {
// generates a link to the RSS feed for this term
_feedManager.Register(part.Name, "rss", new RouteValueDictionary { { "term", part.Id } });
return null;
}),
ContentShape("Parts_TermPart", () => {
var pagerParameters = new PagerParameters();
var httpContext = _httpContextAccessor.Current();
if (httpContext != null) {
pagerParameters.Page = Convert.ToInt32(httpContext.Request.QueryString["page"]);
}
var pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
var taxonomy = _taxonomyService.GetTaxonomy(part.TaxonomyId);
var totalItemCount = _taxonomyService.GetContentItemsCount(part);
var partSettings = part.Settings.GetModel<TermPartSettings>();
if (partSettings != null && partSettings.OverrideDefaultPagination) {
pager.PageSize = partSettings.PageSize;
}
The question is where is TermPart & TermPartSettings defined?
Thanks in advance
The TermPartSettings are in the Modules/Orchard.Taxonomies/Settings folder. The TermPart itself is in the Modules/Orchard.Taxonomies/Models directory. Don't know what you want with that information though, because you shouldnt edit an Orchard's module code.
When you create a new Taxonomy in the dashboard of Orchard, a new content type is created under Content Definition. It is called YourTaxonomy Term. This content type has a setting called 'override the default page size', where you can define your own page size.

Welding a ContentPart having a ContentField

I'm trying to Weld my custom ContentPart SitesPart containing a ContentField of type TaxonomyField but it is not working for me. When i attach this part from UI it works perfectly fine and i see the TaxonomyField in edit mode as well as in display mode.
Following is the Activating method of my ContentHandler.
protected override void Activating(ActivatingContentContext context)
{
if (context.ContentType == "Page")
{
context.Builder.Weld<SitesPart>();
}
}
I tried to go deep into the Weld function and found out that it is not able to find correct typePartDefinition. It goes inside the condition if (typePartDefinition == null) which creates an empty typePartDefinition with no existing ContentFields etc.
// obtain the type definition for the part
var typePartDefinition = _definition.Parts.FirstOrDefault(p => p.PartDefinition.Name == partName);
if (typePartDefinition == null) {
// If the content item's type definition does not define the part; use an empty type definition.
typePartDefinition =
new ContentTypePartDefinition(
new ContentPartDefinition(partName),
new SettingsDictionary());
}
I would be highly thankful for any guidance.
Oh, you are totally right, the part is welded but if there are some content fields, they are not welded. The ContentItemBuilder try to retrieve the part definition through the content type definition on which we want to add the part. So, because it's not possible, a new content part is created but with an empty collection of ContentPartFieldDefinition...
I think that the ContentItemBuilder would need to inject in its constructor and use a ContentPartDefinition or more generally an IContentDefinitionManager... But, for a quick workaround I've tried the following that works
In ContentItemBuilder.cs, replace this
public ContentItemBuilder Weld<TPart>()...
With
public ContentItemBuilder Weld<TPart>(ContentPartDefinition contentPartDefinition = null)...
And this
new ContentPartDefinition(partName),
With
contentPartDefinition ?? new ContentPartDefinition(partName),
And in you part handler, inject an IContentDefinitionManager and use this
protected override void Activating(ActivatingContentContext context) {
if (context.ContentType == "TypeTest") {
var contentPartDefinition = _contentDefinitionManager.GetPartDefinition(typeof(FruitPart).Name);
context.Builder.Weld<FruitPart>(contentPartDefinition);
}
}
Best
To attach a content part to a content type on the fly, you can use this in your handler
Filters.Add(new ActivatingFilter<YourContentPart>("YourContentType"));
There are many examples in the source code
Best

Resources