I have a common Page class which the rest of my app pages inherit from.
I'm writing the buttons in code but I'd like to replicate the way prims does it as it more predictable/readable for a beginner. e.g.
This is current method. How do I change the Command property below to do what the button code does i.e
var im_Logo = new ImageButton
{
Margin = new Thickness(0),
Padding = new Thickness(0),
Source = "blalogo",
BackgroundColor = Color.Transparent,
HorizontalOptions = LayoutOptions.Start,
Command = new Command(GoHome)// This works but other pages are not so easy.
};
void GoHome(object obj)
{
Navigation.PopToRootAsync();
}
Plus I'm just curious how you write Command="{prism:NavigateTo 'path/to/navigate'}" in code.
If I could attach a Viewmodel to this 'code' page, it would also solve the problem as the Viewmodels I have have all the Prism stuff built in.(Supplied by infragistics)
Edit Update: I'm adding full class of page I'm creating in code. I thought writing a common class for multiple pages to use would be simple but I'm stumped.
My error on these fails are when clicking on the Search button which I'll concentrate on for now is.
11-06 16:28:54.988 D/Mono (30123): Loading reference 0 of System.Drawing.Common.dll asmctx DEFAULT, looking for mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
11-06 16:28:54.988 D/Mono (30123): Assembly Ref addref System.Drawing.Common[0xc7e18f60] -> mscorlib[0xe5c08580]: 70
Loaded assembly: System.Drawing.Common.dll [External]
11-06 16:28:55.040 D/EGL_emulation(30123): eglMakeCurrent: 0xc9270ce0: ver 2 0 (tinfo 0xc8d25b10)
**System.NullReferenceException:** 'Object reference not set to an instance of an object.'
using iBasisAppV1.ViewModels;
using Prism.Navigation;
using Prism.Navigation.Xaml;
using Syncfusion.XForms.BadgeView;
using Syncfusion.XForms.Buttons;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Xamarin.Forms;
namespace iBasisAppV1.Views.Templates
{
public class CommonToolbarPage : ContentPage
{
public CommonToolbarPage()
{
NavigationPage.SetHasBackButton(this, false);
ShowDefaultTitle();
//this.BindingContext= new CommonToolbarPageViewModel(navigationService);
}
private void ShowDefaultTitle()
{
var im_Logo = new ImageButton
{
Margin = new Thickness(0),
Padding = new Thickness(0),
Source = "boilerparts",
BackgroundColor = Color.Transparent,
HorizontalOptions = LayoutOptions.Start,
Command = new NavigateToExtension { Name = $"/Home" }
//Command = new Command(GoHome)
};
var b_search = new SfButton
{
HorizontalTextAlignment = TextAlignment.End,
HorizontalOptions = LayoutOptions.FillAndExpand,
FontSize = 26,
TextColor = Color.White,
BackgroundColor = Color.Transparent,
Margin = new Thickness(0),
Padding = new Thickness(0),
FontFamily = "UIFontIcons",
Text = (String)Application.Current.Resources["Search"],
//Command = new NavigateToExtension { Name = "../Search" } //Not Work
//Command = new NavigateToExtension { Name = "Search" } //Not Work
//Command = new NavigateToExtension { Name = $"{nameof(Search)}" } //Not Work
// Command = new NavigateToExtension { Name = $"../{nameof(Search)}" } //Not Work
//Command = new Command(ShowSearch)// Works
};
var boxView = new BoxView
{
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.Red,
Margin = new Thickness(0,0,0,0),
};
SfButton sfButton = new SfButton
{
CornerRadius = 4,
HorizontalOptions = LayoutOptions.End,
VerticalOptions= LayoutOptions.Center,
Style = (Style)Application.Current.Resources["IconButtonStyle"],
Text = (String)Application.Current.Resources["Cart"],
FontFamily = "UIFontIcons",
TextColor = Color.White,
// Command = new Command(GoCart)
};
var imSfBadgeView = new SfBadgeView
{
BadgeText = "4",
Margin = new Thickness(0, 0, 10, 0),
Padding = new Thickness(0),
WidthRequest = 40,
Content = sfButton,
HorizontalOptions = LayoutOptions.EndAndExpand,
VerticalOptions = LayoutOptions.Center,
BackgroundColor = Color.Transparent,
BadgeSettings = new BadgeSetting
{
BackgroundColor= (Color)Application.Current.Resources["PrimaryColor"],
BadgeType = BadgeType.None,
FontSize = 10,
Stroke = (Color)Application.Current.Resources["Gray-White"],
StrokeWidth = 1,
Offset = new Point(-10, 10)
}
};
var layout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
HorizontalOptions=LayoutOptions.FillAndExpand,
BackgroundColor = (Color)Application.Current.Resources["HeaderColor"]
};
var Endlayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.EndAndExpand,
};
if (this.GetType().Name.ToLower() != "search")
Endlayout.Children.Add(b_search);
Endlayout.Children.Add(imSfBadgeView);
layout.Children.Add(im_Logo);
layout.Children.Add(Endlayout);
NavigationPage.SetTitleView(this, layout);
}
private void ShowSearch(object obj)
{
Navigation.PushAsync(new Search());
}
private void cancel(object obj)
{
ShowDefaultTitle();
}
void GoCart(object obj)
{
Navigation.PushAsync(new Home());
}
void GoHome(object obj)
{
Navigation.PopToRootAsync();
// Navigation.PushAsync(new NavigationPage(new Home()));
//NavigationService.NavigateAsync("/MainPage/NavigationPage/ViewA");
}
}
}
If you want the exact match, here we go...
var im_Logo = new ImageButton
{
Margin = new Thickness(0),
Padding = new Thickness(0),
Source = "blalogo",
BackgroundColor = Color.Transparent,
HorizontalOptions = LayoutOptions.Start,
Command = new NavigateToExtension {Name = "/path/to/navigate"}
};
void GoHome(object obj)
{
Navigation.PopToRootAsync();
}
And you will need the following import:
using Prism.Navigation.Xaml;
Long story short, Prism use this class to create a command which can use INavigationService accessing the container in Application.Current. If you check the source code in Github you will see how all the magic happens.
https://github.com/PrismLibrary/Prism/blob/master/src/Forms/Prism.Forms/Navigation/Xaml/NavigateToExtension.cs
If you want to do it in ViewModel, then you need a INavigationService.
Then you can use it like:
await NavigationService.NavigateAsync(nameof(YourView));
So like
Command = new Command(async () => await NavigationService.NavigateAsync("YourView"));
NavigateAsync uses URI parameters, you can use ../ and ../YourView.
I like the nameof() method eg. await NavigationService.NavigateAsync($"../{nameof(YourView)}"));
I have a xamarin forms application that receives data from the database. The database gives "Car" data back. Those objects all have a couple of properties. On of those properties decides what kind of view should be shown on the screen. So a car could have a property named "TypeOfView" with a value "Entry" or "Picker" etc..
The problem is a follows: How can I dynamically create views based on that property and how can that be bind to objects in a list in the viewmodel?
// This is the codebehind where UI controls get created
BindingContext = DependencyInjectionService.Get<CheckListEditViewModel>();
var stack = new StackLayout()
{
Orientation = StackOrientation.Vertical,
Padding = 5
};
for (int i = 0; i < (BindingContext as CheckListEditViewModel).CheckListItems.Count; i++)
{
var item = (BindingContext as CheckListEditViewModel).CheckListItems[i];
var description = new Label()
{
Text = item.Description
};
stack.Children.Add(description);
if ((item.ChecklistItemType == Domain.ChecklistItemType.Number))
{
var numerEntry = new Entry();
numerEntry.Keyboard = Keyboard.Numeric;
numerEntry.TextChanged += MyMethod;
numerEntry.SetBinding(Entry.TextProperty, new Binding(mode: BindingMode.TwoWay, path: "Value", source: item));
stack.Children.Add(numerEntry);
// this is to test if the binding worked
var testLabelBindingTesting = new Label();
testLabelBindingTesting.SetBinding(Label.TextProperty, new Binding(mode: BindingMode.TwoWay, path: "Value", source: item));
stack.Children.Add(testLabelBindingTesting);
}
else if ((item.ChecklistItemType == Domain.ChecklistItemType.Email))
{
var numerEntry = new Entry();
numerEntry.Keyboard = Keyboard.Email;
stack.Children.Add(numerEntry);
}
}
Content = stack;
// The list is in the viewmodel class:
public ObservableCollection<ChecklistItem> CheckListItems { get; set; }
protected override void OnAppearing()
{
base.OnAppearing();
Device.BeginInvokeOnMainThread( () =>
{
WaitingIndicator.IsRunning = true;
var dataModel = new ClassListViewModel();
ListViewClass.ItemsSource = dataModel.Classes;
ListViewClass.IsPullToRefreshEnabled = true;
ListViewClass.RefreshCommand = dataModel.RefreshCommand;
ListViewClass.BackgroundColor = Color.FromHex("#BDBAB6");
ListViewClass.RowHeight = 200;
ListViewClass.SeparatorVisibility = SeparatorVisibility.None;
ListViewClass.ItemTemplate = new DataTemplate(Function);
ListViewPagningBehavior ListViewBehaviour = new ListViewPagningBehavior();
ListViewBehaviour.Converter = new ItemVisibilityEventArgstemConverter();
ListViewBehaviour.Command = dataModel.LoadMoreCommand;
ListViewClass.Behaviors.Add(ListViewBehaviour);
//BindingContext = dataModel;
ListViewClass.SetBinding(ListView.IsRefreshingProperty, "IsBusy");
ListViewClass.BindingContext = dataModel;
stack.Children.Remove(WaitingIndicator);
});
i am flipping to the above page from another page
my problem is that the page is not showing until the bindingcontext is finishing
but i want to show the waiting indicator to the user while waiting binding
I want to make my avatar image which is in a circle clickable. After click it has to be displayed on screen like in FB. So how I can implement this in my code?
listView.Header = "";
listView.HeaderTemplate = new DataTemplate(() =>
{
var avatarLayout = new StackLayout()
{
HeightRequest = 350,
};
var grid = new Grid();
grid.HeightRequest = 400;
grid.BackgroundColor = Color.White;
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());
var bgrImg = new Image();
bgrImg.Aspect = Aspect.Fill;
bgrImg.Source = ImageSource.FromFile("abstract_background.jpg");
var avImg = new CircleImage();
avImg.VerticalOptions = new LayoutOptions(LayoutAlignment.Center, false);
avImg.Source = ImageSource.FromFile("about_background.png");
grid.Children.Add(bgrImg, 0, 0);
grid.Children.Add(avImg);
Grid.SetRowSpan(avImg, 2);
avatarLayout.Children.Add(grid);
Example of my
avatar
You can make an element tappable by using a GestureRecognizer
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += (s, e) => {
// handle the tap
};
image.GestureRecognizers.Add(tapGestureRecognizer);
Hey people, I've this huge problem loading a symbol from a swf file in the application at runtime. I want to load it and pass it as a argument to another class where it could be used further. The symbol name is passed on from the array collection from the "o" object. Can anybody please tell me what's the right way to go about it.. Thanks in advance..!!
Following is the code for reference..
public override function Show(o:ObjectProxy):void
{
var _this:Weather;
var _super:ContentItem;
var item:WeatherItem;
var items:ArrayCollection;
var widgetCount:Number;
var headlineFontSize:int;
var conditionsIconThemeLoader:Loader;
this.m_weatherWidgetContainer = new HBox();
super.Show(o);
_this = this;
_super = super;
(undefined == o["HeadlineFontSize"]) ? headlineFontSize = 20 : headlineFontSize = o["HeadlineFontSize"];
if (undefined != o["direction"])
this.m_textDirection = o["direction"];
if (o.LargeUrl.Forecast is ArrayCollection)
items = ArrayCollection(o.LargeUrl.Forecast);
else
items = new ArrayCollection([o.LargeUrl.Forecast]);
widgetCount = this.m_computeWidgetSpace(items.length);
conditionsIconThemeLoader = new Loader();
conditionsIconThemeLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void
{
for(var i:uint = 0; i < widgetCount; i++)
{
var symbolClass:Class = e.currentTarget.loader.contentLoaderInfo.applicationDomain.currentDomain.getDefinition(int(items[i].condition)) as Class;
var symbolInstance:Sprite = new symbolClass();
item = new WeatherItem();
item.Show(items[i], headlineFontSize, symbolInstance, widgetCount);
_this.m_weatherWidgetContainer.addChild(item);
}
});
conditionsIconThemeLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent):void
{
Alert.show("Failure loading " + WidgetStylesheet.instance.Weather_Widget_Theme + ".swf");
});
// Attempt to load theme weather icon file
conditionsIconThemeLoader.load(new URLRequest("assets/animation/" + WidgetStylesheet.instance.Weather_Widget_Theme + ".swf"));
super.media.addChild(this.m_weatherWidgetContainer);
}
Heres the answer
public override function Show(o:ObjectProxy):void
{
var _this:Weather;
var _super:ContentItem;
var conditionsIconThemeLoader:Loader;
var loaderContext:LoaderContext;
this.m_weatherWidgetContainer = new HBox();
this.m_weatherWidgetContainer.percentHeight = 100;
this.m_weatherWidgetContainer.percentWidth = 100;
super.Show(o);
_this = this;
(undefined == o["HeadlineFontSize"]) ? this.m_headlineFontSize = 20 : this.m_headlineFontSize = o["HeadlineFontSize"];
if (undefined != o["direction"])
this.m_textDirection = o["direction"];
if (o.LargeUrl.Forecast is ArrayCollection)
this.m_items = o.LargeUrl.Forecast;
else
this.m_items = new ArrayCollection([o.LargeUrl.Forecast]);
conditionsIconThemeLoader = new Loader();
loaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
conditionsIconThemeLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.m_loaderSuccess);
conditionsIconThemeLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.m_loaderFail);
// Attempt to load theme weather icon file
conditionsIconThemeLoader.load(new URLRequest("assets/animation/" + WidgetStylesheet.instance.Weather_Widget_Theme + ".swf"), loaderContext);
this.m_weatherWidgetContainer.addEventListener(FlexEvent.CREATION_COMPLETE, this.m_drawHorizontalLine);
super.media.addChild(this.m_weatherWidgetContainer);
}