I have Xamarin forms time picker following custom renderer for IOS
[assembly: ExportRenderer(typeof(TimePicker), typeof(Time24PickerRenderer))]
namespace LabOraTimeStamp.iOS.Renderers
{
public class Time24PickerRenderer:TimePickerRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e)
{
base.OnElementChanged(e);
var timePicker = (UIDatePicker)Control.InputView;
timePicker.Locale = new NSLocale("no_nb");
//Get the Done button
var toolbar = (UIToolbar)Control.InputAccessoryView;
var doneBtn = toolbar.Items[1];
//Set the Done to OK
doneBtn.Title = "OK";
}
}
}
I wanted to change the default "done" to "Ok".
1) How can I do that? the line mentioned above for setting the title does not affect anything.
2) I already implemented localization for xamarin forms.I just wanted to use existing Resx values from custom renderer to show the string for appropriate culture.How can I achieve that?
So the reason why your code isn't working is because the done button is created with the UIBarButtonSystemItem.Done style. It doesn't care about the Title property. Renderer code here.
To work around that issue you could try replacing the Xamarin created done button with your own custom Ok button.
//Get the Done button
var toolbar = (UIToolbar)Control.InputAccessoryView;
// Replace Xamarin's buttons with custom ones.
var spacer = new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace);
var doneButton = new UIBarButtonItem();
doneButton.Title = "OK";
doneButton.Clicked += (o, a) => Control.ResignFirstResponder();
toolbar.SetItems(new [] { spacer, doneButton}, false);
Related
I really want to implement a loading circle in the searchbar (overriding the cancel button while loading) on android like Netflix.
Currently Im getting the cancel button with
var searchBttId = searchView.Resources.GetIdentifier("android:id/search_close_btn", null, null);
var imbCancel = (searchView.FindViewById(searchBttId) as Android.Widget.ImageView)
but I dont know how to add a progresscircle and how to interact with it. I thought of adding it with AddView, but nothing pops up when testing.
Test:
var _v = new Android.Widget.ImageView(Context) { };
_v.SetBackgroundColor(new Android.Graphics.Color(200, 0, 0));
var c = new LayoutParams(500, 500);
_v.LayoutParameters = c;
searchView.AddView(_v);
I really want to implement a loading circle in the searchbar (overriding the cancel button while loading) on android like Netflix.
According to your description, you want to override searchbar's search_close_btn using other icon, like loading circle? Am I right?
If yes, I suggest you can use custom render to change searchbar's search_close_btn image.
Firstly, create custom Searchbar that inherit SearchBar in Form.cs.
public class MySearchBar:SearchBar
{
}
Then implementing custom render in Android platform.
[assembly: ExportRenderer(typeof(MySearchBar), typeof(MySearchBarRenderer))]
namespace demo3.Droid
{
public class MySearchBarRenderer: SearchBarRenderer
{
public MySearchBarRenderer(Context context):base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
if (Control != null)
{
var searchView = Control;
int searchViewCloseButtonId = Control.Resources.GetIdentifier("android:id/search_close_btn", null, null);
var closeIcon = searchView.FindViewById(searchViewCloseButtonId);
(closeIcon as ImageView).SetImageResource(Resource.Drawable.plu3);
}
}
}
}
Please see the gif:
About Custom Render, you can take a look:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/entry
I just started with Xamarin forms and followed this example. But for the landscape mode it always has Navigation drawer opened. Is this default behavior? Below is my code
public class NavigationDrawer : MasterDetailPage // Navigation Drawer using MasterDetailPage
{
public override bool ShouldShowToolbarButton()
{
return true;
}
ContentPage gotoPage;
public NavigationDrawer()
{
Title = "Navigation Drawer Using MasterDetailPage";
string[] myPageNames = { "Camera2 Demo", "Second", "Third" };
SizeChanged += NavigationDrawer_SizeChanged;
ListView listView = new ListView
{
ItemsSource = myPageNames,
};
this.Master = new ContentPage
{
Title = "Options",
Content = listView,
Icon = "hamburger.png"
};
listView.ItemTapped += (sender, e) =>
{
switch (e.Item.ToString())
{
case "Camera2 Demo":
gotoPage = new CameraPage();
break;
case "Second":
gotoPage = new SecondPage();
break;
case "Third":
gotoPage = new ThirdPage();
break;
default:
gotoPage = new NavigationPage1();
break;
}
Detail = new NavigationPage(gotoPage);
((ListView)sender).SelectedItem = null;
this.IsPresented = true;
};
Detail = new NavigationPage(new HomePage());
IsPresented = false;
//// For Windows Phone, provide a way to get back to the master page.
//if (Device.OS == TargetPlatform.WinPhone)
//{
// (this.Detail as ContentPage).Content.GestureRecognizers.Add(
// new TapGestureRecognizer((view) =>
// {
// this.IsPresented = true;
// }));
//}
}
Question
1) How would I control opening and closing of Navigation Drawer? I found a way where it would give us control over the width of the navigation Drawer. Here is the Link. But is this the best option available right now?
1) Since project requires to be crossplaform Xamarin forms controls seems to be one of the option.
2) Should we go with Custom controls and not Xamarin forms controls?
I just started with Xamarin sample code would appreciate if someone can guide me through this.
1) How would I control opening and closing of Navigation Drawer?
Use this.IsPresented = true; to open and this.IsPresented = false; to close the drawer.
About the other questions I don't understand you good, but depending on your requirements, you should create custom controls or download one from NuGet.
Note:
I believe the most important thing for a beginner is to learn how to implement a native code using DependencyService and also to use Design patterns like MVVM.
You would need to set MasterBehavior = MasterBehavior.Popover on the MasterDetailPage to force it to exhibit the behaviour you are after, otherwise it will default to MasterBehavior.Default, which in Landscape mode will be always open.
Being a newbie to Xamrin I am struggling to adding some HTML to a StackLayout via Xamarin Forms. I have tried quite a few things and had a Google around.
Firstly I can't work out which bindable object I am supposed to be using. As I cannot find a straight answer on Google/Xamarin I am going to assume this is not as easy I was hoping.
var nameEntry = new Label ();
nameEntry.SetBinding (Label.TextProperty, "Club.ClubName");
var webView = new WebView ();
webView.SetBinding ( ??? , "Club.Description");
var content = new StackLayout {
Children = {
nameEntry,
???
}
};
I am not sure if this is possible within Xamarin forms itself. Can anyone help?
I should point out my data for the form is being retrieved asynchronously on a remote json endpoint
protected override void OnAppearing ()
{
base.OnAppearing ();
if (ViewModel == null || ViewModel.IsLoading)
return;
ViewModel.LoadItemsCommand.Execute (Club.ClubId);
}
My remote json api contains, Description contatins a HTML snippet which I would like to use.
{
ClubName: "Stourbridge",
Description: "<p>This club meets every TWO weeks on a <b>Friday</b>.</p>"
...
}
Try the following example that will show how to do the bindings.
Note that you have to use a HtmlWebViewSource to achieve this, and bind the WebView.Source to this.
Clicking the button will change the view model and update the WebView appropriately to the newly changed text.
StackLayout objStackLayout = new StackLayout();
MyView objMyView = new MyView();
objMyView.MyHtml = "<html><head></head><body><h1>Title</h1><p>Some body text</p></body></html>";
HtmlWebViewSource objHtmlWebViewSource = new HtmlWebViewSource();
objHtmlWebViewSource.SetBinding(HtmlWebViewSource.HtmlProperty, "MyHtml");
objHtmlWebViewSource.BindingContext = objMyView;
WebView objWebview = new WebView();
objWebview.HorizontalOptions = LayoutOptions.FillAndExpand;
objWebview.VerticalOptions = LayoutOptions.FillAndExpand;
objWebview.Source = objHtmlWebViewSource;
Button objMyButton2 = new Button();
objMyButton2.Text="Change Html";
objMyButton2.Clicked+=((o2,e2)=>
{
objMyView.MyHtml = "<html><head></head><body><h1>Title</h1><p>Some body text that has changed.</p></body></html>";
});
objStackLayout.Children.Add(objMyButton2);
objStackLayout.Children.Add(objWebview);
The view model is just a simple one with a bindable property as below:-
public class MyView
: Xamarin.Forms.View
{
public static readonly BindableProperty MyHtmlProperty = BindableProperty.Create<MyView, string>(p => p.MyHtml, default(string));
public string MyHtml
{
get { return (string)GetValue(MyHtmlProperty); }
set { SetValue(MyHtmlProperty, value); }
}
}
Before clicking the button gives:-
After clicking the button, adjusts the view model, and automatically updates the control via the binding giving:-
Using MonoDevelop, I have been looking at an IOS implementation of a side slide out menu using FlyoutNavigationController, but have hit a couple of stumbling blocks.
Firstly, how can you access the font elements of the generated list?
I can easily modify row heights etc, but am unsure of how to proceed with modifying the list items, can this be down with a tablesource and item styling?
Secondly, how to open a view from this list?
Currently an empty view is used by default but new views are to be opened from the side menu list, I have tried using the push navigation controller but it fails to open.
Any ideas are more than welcome.
navigation = new FlyoutNavigationController();
navigation.View.Frame = UIScreen.MainScreen.Bounds;
View.AddSubview(navigation.View);
navigation.NavigationRoot = new RootElement ("Menu List")
{
new Section ("Menu List")
{
from page in SlideList
select new StringElement (page.title) as Element
}
};
navigation.NavigationTableView.BackgroundColor = UIColor.DarkGray;
navigation.NavigationTableView.RowHeight = 30;
navigation.NavigationTableView.SeparatorStyle = UITableViewCellSeparatorStyle.SingleLine;
navigation.NavigationTableView.SeparatorColor = UIColor.LightGray;
navigation.NavigationTableView.SectionHeaderHeight = 60;
//navigation.NavigationTableView.DataSource = SlideList;
//navigation.ViewControllers = Array.ConvertAll (MenuItems, title => new UINavigationController (new TaskPageController (navigation, title)));
navigation.ViewControllers = Array.ConvertAll (MenuItems, title => new TaskPageController (navigation, title));
this.NavigationItem.LeftBarButtonItem = new UIBarButtonItem (UIBarButtonSystemItem.Action, delegate {
navigation.ToggleMenu();
});
I haven't used the FlyOutNavigationController before, but I took a look at this example:
https://github.com/xamarin/FlyOutNavigation
It looks like you're supposed to have the same number of StringElements as Controllers. For the ViewControllers array, it looks like you can supply your own custom controllers instead of just plain ViewControllers. After that, clicking a list item should automatically navigate to the appropriate controller.
In regards to styling, looking at the source for this NavigationController, I don't see much in terms of being able to stylize the cells. I did a quick search for how to go about styling MonoTouch Dialog lists and it looks like there isn't an easy way without subclassing elements:
Monotouch Dialog: Styling Elements
However, I can share with you how I've accomplished the two questions you asked without the Dialog framework.
You can create a custom class that extends UITableViewSource:
http://docs.xamarin.com/guides/ios/user_interface/tables/part_2_-_populating_a_table_with_data
In the GetCell method override, you can grab an instance of the cell's label and set the font like so:
cell.TextLabel.Font = UIFont.FromName("TitlingGothicFB Cond", 20);
Another thing you can do with your custom UITableViewSource class is create a custom event:
public event EventHandler ListItemSelected;
Inside the RowSelected method you can dispatch this event:
public override void RowSelected (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
ListItemSelected(this, new MyCustomEventArgs(indexPath.Row));
}
In the controller class that was responsible for instantiating this TableSource, you can listen and handle this event like so:
var customTableSource = new CustomTableSource(myList);
MyTable.Source = customTableSource;
customTableSource.ListItemSelected += (object sender, EventArgs e) => {
if((e as MyCustomEventArgs).rowSelected == 1){
this.NavigationController.PushViewController(new MyNextViewController(), true));
}
}
I'm trying to create a DevEx drop down button. Unfortunately, I'm running into two problems I can't figure out:
1) I can't get the popup menu to skin correctly, i.e. it doesn't skin as "Office 2010 Blue". The code I'm using is shown below:
private void InitializeSendToPricingSheetButton()
{
var barManager = new BarManager();
if (barManager.Controller == null) barManager.Controller = new BarAndDockingController();
barManager.Controller.PaintStyleName = "Skin";
barManager.Controller.LookAndFeel.UseDefaultLookAndFeel = false;
barManager.Controller.LookAndFeel.SkinName = "Office 2010 Blue";
barManager.ItemClick += HandleSendToPricingSheetClick;
barManager.Items.AddRange(new[] { new BarButtonItem(barManager, "Foo"), new BarButtonItem(barManager, "Bar"), new BarButtonItem(barManager, "Baz") });
var popupMenu = new PopupMenu { Manager = barManager };
foreach (var barItem in barManager.Items) popupMenu.ItemLinks.Add((BarItem)barItem);
popupMenu.ItemLinks[1].BeginGroup = true;
dropDownButtonSendToPricingSheet.DropDownControl = popupMenu;
}
2) This button is on a form. If the form loses focus (e.g. I click on Firefox), the pop-up menu still remains on-top. It won't go away until clicked.
Any suggestions would be much appreciated. Thanks for helping me deal with DevEx insanity.
I have solution to your second question.
You should add drop down button event handler as below:
dropDownButton1.LostFocus += new EventHandler(HidePopUp);
Handler method should be as below:
private void HidePopUp(object sender,object e)
{
dropDownButton1.HideDropDown();
}
For your second question, you should assign value to the bar manager property as:
BarManager manager = new BarManager();
manager.Form = this; // refers to current form
Find below link for reference
https://www.devexpress.com/Support/Center/Question/Details/Q274641
It is probably simpler to use DefaultLookAndFeel
Add this comp to your form and set the theme you'd like to use.
There is no need to set the theme for individual components.
defaultLookAndFeel1.LookAndFeel.SetSkinStyle("Office 2010 Blue");