I have localised the whole app but not able to localise the date picker. A bit of searchin in the forum gave me few answers like this one
but i cant find a properties folder with the resx for different lang for toolkit! I have jus added the toolkit reference in the solution explorer under reference and thats im able to access date picker. I have made a folder called toolkit.content to put the ok and cancel images.
so how do i add the resx for the toolkit date picker :(
You can also create a custom control which inherits from the original DatePicker.
public class MyDatePicker : Microsoft.Phone.Controls.DatePicker
{
public string PickerPageHeader
{
get { return (string)GetValue(PickerPageHeaderProperty); }
set { SetValue(PickerPageHeaderProperty, value); }
}
// Using a DependencyProperty as the backing store for PickerPageHeader. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PickerPageHeaderProperty =
DependencyProperty.Register("PickerPageHeader", typeof(string), typeof(MyDatePicker)
, new PropertyMetadata("Choose date text in your language"));
public MyDatePicker()
{
base.PickerPageUri = new Uri("/Sample;component/CustomControls/MyDatePickerPage.xaml?Header=" + PickerPageHeader, UriKind.Relative);
//Don't forget to change the project name and xaml location
}
}
And create picker page xaml file in a CustomControls folder:
<toolkit:DatePickerPage
x:Class="Sample.MyDatePickerPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
/>
Code behind:
public partial class MyDatePickerPage : Microsoft.Phone.Controls.DatePickerPage
{
public MyDatePickerPage ()
{
InitializeComponent();
foreach (var item in base.ApplicationBar.Buttons)
{
IApplicationBarIconButton button = item as IApplicationBarIconButton;
if (null != button)
{
if ("DONE" == button.Text.ToUpper())
{
button.Text = "done in your language";
}
else if ("CANCEL" == button.Text.ToUpper())
{
button.Text = "cancel in your language";
}
}
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
(base.FindName("HeaderTitle") as TextBlock).Text = e.Uri.OriginalString.Substring(e.Uri.OriginalString.IndexOf("Header=") + 7);
base.OnNavigatedTo(e);
}
}
You have to get the source for the ToolKit and rebuild it with your localization
WP7 ToolKit Source
It's very simple: Parameter - Language.
Xaml code:
<toolkit:DatePicker Language="ru-RU" Margin="-12, 0" Value="{Binding BirthDate, Mode=TwoWay}" />
Related
I want to hide navigation bar button in xamarin. how can i do that using binding. Toolbar item doesn't have "IsVisible" property.
Following is my xaml code
please help me to sort out this issue.
I would suggest to build a bindable ToolBoxItem. That way you can control the visibility through a view model property.
An implementation could look like that:
public class BindableToolbarItem : ToolbarItem
{
public static readonly BindableProperty IsVisibleProperty = BindableProperty.Create(nameof(IsVisible), typeof(bool), typeof(BindableToolbarItem), true, BindingMode.TwoWay, propertyChanged: OnIsVisibleChanged);
public bool IsVisible
{
get => (bool)GetValue(IsVisibleProperty);
set => SetValue(IsVisibleProperty, value);
}
private static void OnIsVisibleChanged(BindableObject bindable, object oldvalue, object newvalue)
{
var item = bindable as BindableToolbarItem;
if (item == null || item.Parent == null)
return;
var toolbarItems = ((ContentPage)item.Parent).ToolbarItems;
if ((bool)newvalue && !toolbarItems.Contains(item))
{
Device.BeginInvokeOnMainThread(() => { toolbarItems.Add(item); });
}
else if (!(bool)newvalue && toolbarItems.Contains(item))
{
Device.BeginInvokeOnMainThread(() => { toolbarItems.Remove(item); });
}
}
}
As you have discovered yourself there is not IsVisible. So you will have to implement functionality like that yourself if you still want it.
Another way would be to handle it in the pages' code-behind and remove or add the toolbar item whenever needed.
Adding and removing is simple, just add and remove items to the ToolbarItems collection: ToolbarItems.RemoveAt(0); for instance will remove the first toolbar item.
Putting #Gerald answer in action, it would be done this way:
void Done_Clicked(System.Object sender, System.EventArgs e)
{
//Do somthing and hide the done item
ShowDoneToolbarItem(false, (ToolbarItem)sender);
}
void Entry_Focused(System.Object sender, Xamarin.Forms.FocusEventArgs e)
{
//Show the done item
ShowDoneToolbarItem(true);
}
void ShowDoneToolbarItem(bool show, ToolbarItem item = null)
{
if(show)
{
ToolbarItem done = new ToolbarItem();
done.Text = "Done";
done.Clicked += Done_Clicked;
ToolbarItems.Add(done);
}
else if(item != null)
{
ToolbarItems.Remove(item);
}
}
This is cleaner and works from the code behind.
Well we need the IsVisible property for the front end, as xamarin doesn't have it, you can use Device.RuntimePlatform to check in real time which device the application is running. Since my code is in .cs of the XAML file, we can use xaml .cs to insert items into the screen.I put if () to do the logic and check if my device is on which platform, because I don't want it to display in UWP a toolbar.
The code is in .cs of the XAML file:
public kingTest()
{
InitializeComponent();
if((Device.RuntimePlatform == "Android")||(Device.RuntimePlatform == "iOS"))
{
ToolbarItem toolbar = new ToolbarItem();
toolbar.IconImageSource = "ic_ToolBar.png";
this.ToolbarItems.Add(toolbar);
}
};
I've achieved this easily using overloaded constructors. Here's an example:
View (add the name property):
<ContentPage x:Name="ContentPage"
<!-- rest of the tag -->
/>
Code-behind (add the toolbar items):
public partial class ExamplePage : ContentPage
{
public ExamplePage()
{
InitializeComponent();
BindingContext = this;
var saveToolbarItem = new ToolbarItem { Text = "Save" };
saveToolbarItem.Clicked += YourMethodToBeRan;
ContentPage.ToolbarItems.Add(saveToolbarItem);
}
public ExamplePage(Object object)
{
InitializeComponent();
BindingContext = this;
var updateToolbarItem = new ToolbarItem { Text = "Update" };
updateToolbarItem.Clicked += YourMethodToBeRan;
var deleteToolbarItem = new ToolbarItem { Text = "Delete" };
deleteToolbarItem.Clicked += YourMethodToBeRan;
ContentPage.ToolbarItems.Add(updateToolbarItem);
ContentPage.ToolbarItems.Add(deleteToolbarItem);
}
// rest of the class
}
The above pseudocode will add the "Save" toolbar item when the class is instantiated with no parameter, or the "Update" and "Delete" when a parameter is provided.
This isn't as elegant as IsEnabled / IsVisible booleans but it's a step in the right direction. Following this train of thought, you could modify the children of your toolbar during runtime to "show" and "hide" by adding and removing them as children.
Good luck!
I don't know if #tequila slammer's solution fully worked on Xamarin, but for us it only kind of works in .Net Maui (the evolution of Xamarin) and binding the IsVisible property to a variable.
Once the BindableToolbarItem is removed from the ContentPage's list of ToolbarItems, it is disconnected from the object that IsVisible is bound to forever.
For example: We want to use this control to hide or show a ToolbarItem that navigates to the admin screen, if I log in as the administrator on app launch, the item is there...great. If I then log out and log in as a non-admin, the item is not there...perfect. If I then log out and log in as an admin, the item is not there (the propertyChanged: OnIsVisibleChanged never fired)...:-(.
Not a big deal for us, if you want admin access then stopping the app and starting the app to log in as the admin is not a big ask.
In the newest release with .Net 7 the workaround works never more !
The reason is because the toolbar item which revomed will destoyed !
i want to display pdf in webview from url using pdfjs, but i am getting empty view. here is my code
CustomWebView.cs
public class CustomWebView : WebView
{
public static readonly BindableProperty UriProperty = BindableProperty.Create(propertyName: "Uri",
returnType: typeof(string),
declaringType: typeof(CustomWebView),
defaultValue: default(string));
public string Uri
{
get { return (string)GetValue(UriProperty); }
set { SetValue(UriProperty, value); }
}
}
MainPage.xaml
<ContentPage.Content>
<local:CustomWebView Uri="http://veezo2007pkk.somee.com/api/DiagnosticDetail/RetrieveFile/1" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</ContentPage.Content>
App.Android
CustomWebViewRenderer.cs
public class CustomWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
var customWebView = Element as CustomWebView;
Control.Settings.AllowUniversalAccessFromFileURLs = true;
Control.LoadUrl(string.Format("file:///android_asset/pdfjs/web/viewer.html?file={0}", string.Format("file:///android_asset/Content/{0}", WebUtility.UrlEncode(customWebView.Uri))));
}
}
}
it seems look fine, but i dont know why its not showing in webview....
I will assume two things here. One, you're not precious about PDF file being displayed in the WebView. Second you're OK with using 3rd party libraries.
I would suggest using SyncFusion PdfViewer. It's very easy to use and does everything you might want to do with PDFs - maybe not everything but a lot. If you're worried that you will need to pay a lot for these controls, fear not! SyncFusion has a free community license, which you can use (if you're not making more than a $1 mln USD and you don't have a larger team than 5 devs). You might want to have a look at this thread, talking about showing PDF from URL.
I'm currently using telerik in UWP to create list of items, i want to be able to use a browse button and update a certain piece of data in the Telerik-RadDataForm. I have all the bindings setup using MVVM and it displays data fine if it isn't edited on the code side. My XAML is setup as so:
<Data:RadDataForm x:Name="dataform"
HorizontalAlignment="Left" Grid.Row="0"
Grid.RowSpan="2" Grid.Column="2"
VerticalAlignment="Center" Width="454"
Item="{Binding CurrentSceneViewModel, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" CommitMode="Immediate"
ValidationMode="Immediate" Height="664" Margin="0,28" />
The CurrentSceneViewModel is:
public SceneViewModel CurrentSceneViewModel
{
get => _currentSceneViewModel;
set=> _currentSceneViewModel= value;
}
And the data i wish to change is :
public string FileName
{
get => _fileName;
set
{
Scene.SceneFile = value;
_fileName = Path.GetFileName(value);
OnPropertyChanged(nameof(FileName));
}
}
The problem i have is pushing this information to the user interface the code-behind doesn't seem to update the UI, even using PropertyChanged. I'm not sure what else to try ? And if this is something the RadDataform simply doesn't support. It should be noted FileName is a property of CurrentScene ViewModel.
public abstract class BaseViewModel: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected IPageNavigationService navservice = new PageNavigationService();
}
Is the Picker Control available in Xamarin bindable? If so, could someone help on how to use it ? I would like to bind a Picker control with data (XAML approach) that comes from a DB.
The bindable Picker is available since 13th January 2017. Currently, it is contained in version 2.3.4.184-pre1.
If you want to use it, you have to install Xamarin.Forms via nuget using the -Pre flag. Or check the Prerelease checkbox in the nuget UI.
Install-Package Xamarin.Forms -Pre
And then, you can just bind your collection to ItemsSource.
<Picker
Title="Select a Color"
ItemsSource="{Binding Colors}" />
Announcement: https://blog.xamarin.com/new-xamarin-forms-pre-release-2-3-4-pre1-quality-improvements-bindable-picker
It will be released as stable not later than February 2017 (according to the Roadmap)
Yes, You can us the Picker control in Xamarin Forms.
Please check this link for the description: https://developer.xamarin.com/api/type/Xamarin.Forms.Picker/
Thank You.
Example #1 :
Use Extendedpicker of xlabs following is link to implement extended picker
Cs code of extended picker
https://github.com/XLabs/Xamarin-Forms-Labs/blob/master/src/Forms/XLabs.Forms/Controls/ExtendedPicker.cs
Implementation in xaml page:-
https://github.com/XLabs/Xamarin-Forms-Labs/blob/7a58dc349f17351813afa24df97ef7fea545a833/samples/XLabs.Samples/XLabs.Samples/Pages/Controls/ExtendedPickerPage.xaml
Example #2:
Try to create own bendable picker refer following link
https://forums.xamarin.com/discussion/30801/xamarin-forms-bindable-picker
Here is the complete solution:
https://hiranpeiris.com/2017/02/24/how-to-add-a-custom-bindable-property-to-xamarin-forms-control/
Create your custom picker class.
using System.Collections.Generic;
using Xamarin.Forms;
namespace FDNet
{
public class OutletPicker : Picker
{
public static readonly BindableProperty ItemSourceProperty = BindableProperty.Create(nameof(ItemSource), typeof(List<string>), typeof(OutletPicker), null);
public List<string> ItemSource
{
get
{
return (List<string>)GetValue(ItemSourceProperty);
}
set
{
SetValue(ItemSourceProperty, value);
}
}
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == nameof(ItemSource))
{
this.Items.Clear();
if (ItemSource != null)
{
foreach (var item in ItemSource)
{
this.Items.Add(item);
}
}
}
}
}
}
Add XAML reference variable to the Page.
xmlns:local=“clr–namespace:FDNet;assembly=FDNet“
Add the control and bind the property.
<local:OutletPicker Title=“Select“ ItemSource=“{Binding Outlets}“ HorizontalOptions=“Center“ WidthRequest=“300“ />
Now you can see our custom bindable property ItemSource=“{Binding Outlets}“)
Demo.
Outlets = new List<string> { “4G LTE“, “4G Broadband“, “Fiber connection“ };
<local:OutletPicker Title=“Select“ ItemSource=“{Binding Outlets}“ HorizontalOptions=“Center“ WidthRequest=“300“ />
(1)bind picker :
Dictionary dicobj= new Dictionary();
dicobj.Add(1, "abc");
dicobj.Add(2, "xyz");
foreach (var item in dicobj.Values)
{
YorPickerName.Items.Add(item);
}
(2)then get the selected value on SelectedIndexChanged event of picker:
var selval = Service_category.SelectedIndex;
int value = dicobj.ElementAt(selval).Key;
var data = Service_category.Items[selval];
int id = dicval.FirstOrDefault(x => x.Value == data).Key;
I have two pages.
i) HomePage -- which contains one button to display user selected city(by defalut Delhi)
ii) ListPage -- Which contains List box (all cities show here)
So when user clicks on button in the HomePage, then i'll navigate to ListPage to select city.
When user clicks on any city from the list, then i have to dismiss that ListPage and then immediately the selected city should update as button's content in the HomePage.
Please help me how to do the above task.
if you are using "MVVM Light" library then you can use Messenger service Like this....
in second page after selection is changed send a message
Messenger.Default.Send<type>(message,token);
and then in the consructor of page 1 viewmodel
Messenger.Default.Register<type>(this,token,Method);
here token should be same as sender token....
then
void Method(type message)
{
button.content = message;
}
The basic way is to implement the PropertyChanged subscription.
//In your HomePage class
HomePage()
{
ListPage.PropertyChanged +=this.CitySelected //Subscribe to the property changed event
}
void CitySelected(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "NewCity")
{
City selectedCity= (sender as ListPage).NewCity;
}
}
//In your ListPage class
//You should implement INotifyPropertyChanged interface:
ListPage:INotifyPropertyChanged
private city newCity;
public City NewCity
{
get{return newCity;}
set{
newCity=value;
NotifyChange("NewCity");
}
}
void CitySelected(City selected)
{
NewCity=selected;
}
public event PropertyChangedEventHandler PropertyChanged;
public delegate void PropertyChangeHandler(object sender, EventArgs data);
protected void NotifyChange(string args)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(args));
}
}
I would recommend you change your workflow to use the Windows Phone Toolkit ListPicker control. This control matches the style you see in the Settings app of the phone. The ListPicker allows users to tap the selected item and be navigated to another page that offers them a list of available options. Here is an example
<StackPanel>
<TextBlock Text="City"/>
<toolkit:ListPicker ExpansionMode="FullScreenOnly"
FullModeHeader="CITY"
ItemsSource="{Binding Cities}"
SelectedItem="{Binding SelectedCity}">
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<TextBlock Margin="0,20" Text="{Binding Name}" TextWrapping="Wrap"/>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
</StackPanel>
Your DataContext would look something like
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
Cities = new List<City> { new City("Denver"), new City("New York") };
}
public City SelectedCity
{
{ get return _city; }
{ _city = value; OnpropertyChanged("SelectedCity"); }
}
public IEnumerable<City> Cities { get; private set; }
}
This is gonna be very simple. What you have to do is, use NavigationService.Navigate(), and then append the selected city along with the HomePage page uri and in the HomePage page, retrieve the selected city using NavigationContext.QueryString.TryGetValue() and assign the value in your button.
For ex,
In your ListPage.cs,
NavigationService.Navigate(new Uri("/HomePage.xaml?selectedCity=" + "Coimbatore", UriKind.Relative));
In your HomePage.cs,
string selectedCity = "";
NavigationContext.QueryString.TryGetValue("selectedCity", out selectedCity);
button.Content = selectedCity;
Thanks