Telerik control RadAutoComplete is getting reset after updating ItemSource Xamarin - xamarin

I am using Telerik's RadAutoComplete for having an autocomplete field. It is working fine with static data but on the basis of input received by user in autocomplete field, I have to execute the API and fetch data from there. List received in API response will be visible in autocomplete's suggestion view.
As soon as I am assigning my response to the ItemSource of RadAutoComplete, the text entered in the autocomplete is getting reset. For example: If I want to search "Friday", I entered "Fr" in autocomplete field. After receiving the response from the API that "Fr" will be removed from the autocomplete automatically and autocomplete text will be "".
XAML:
<telerikInput:RadAutoComplete
BorderColor="LightGray"
FilteredItemsChanged="autoCompleteUsers_FilteredItemsChanged"
ItemsSource="{Binding UserList}"
SearchThreshold="3"
ShowSuggestionView="True"
SuggestionItemSelected="autoCompleteUsers_SuggestionItemSelected"
TextSearchPath="Name">
<telerikInput:RadAutoComplete.SuggestionItemTemplate>
<DataTemplate>
<StackLayout HeightRequest="20">
<Label
Margin="2"
HorizontalOptions="Start"
Text="{Binding Item.Name}"
TextColor="Black"
VerticalOptions="Center" />
</StackLayout>
</DataTemplate>
</telerikInput:RadAutoComplete.SuggestionItemTemplate>
</telerikInput:RadAutoComplete>
Event
void autoCompleteUsers_FilteredItemsChanged(System.Object sender, Telerik.XamarinForms.Input.AutoComplete.FilteredItemsChangedEventArgs e)
{
var searchedText = (sender as RadAutoComplete).Text;
viewController.GetUserList(searchedText);
}
public async Task GetUserList(string searchedText)
{
// **reassigning userList with the response of API**
UserList = await _APIservice.GetUsers(searchedText);
}

Try using RadAutoCompleteView, it is recommended for Remote search.
https://docs.telerik.com/devtools/xamarin/controls/autocompleteview/autocompleteview-remote-search?_ga=2.230265054.335708323.1661762900-2099335098.1639588237

Related

Navigate to specific page defined on model when Item is Tapped

I'm trying to make a custom home page where pages are listed on an Horizontal scroll view as "Services" so each one of them should navigate to a different Page.
I have a view like this:
<controls:HorizontalScrollView HeightRequest="160"
Orientation="Horizontal"
ItemsSource="{Binding OwnerServicesList}"
x:Name="OwnerServicesSlider"
ItemSelected="OwnerServicesSlider_ItemSelected">
<controls:HorizontalScrollView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Margin="10,0,5,0" WidthRequest="100" HeightRequest="100">
<Image HorizontalOptions="Start" Source="{Binding ImgUrl}" WidthRequest="100" HeightRequest="100" />
<Label Style="{StaticResource BoldLabel}" HorizontalTextAlignment="Center" FontSize="13" LineBreakMode="TailTruncation" Text="{Binding Name}" TextColor="Black"/>
</StackLayout>
</ViewCell>
</DataTemplate>
Im using a custom made controller for a Horizontal Scroll view that works like a listview, every item on tap raises a ItemTappedEventArgs event.
Inside my model i´ve declared a public Page Page { get; set; } for each object in the scroll view.
What im trying to do is recover the tapped element and recover the Page stored in it so that I can Navigate to that specific page.
So far I have something like this:
private void OwnerServicesSlider_ItemSelected(object sender, ItemTappedEventArgs e)
{
var service = OwnerServicesSlider.SelectedItem as Services;
Navigation.PushAsync(service.Page);
}
It shows no errors but when I run it I get a
InvalidOperationException: 'Page must not already have a parent.
Any hint will be appreciated!
as Jason said,maybe the page you would push which is exist in thecurren navigation structure,there is a workaround ,before you push the page :
private void OwnerServicesSlider_ItemSelected(object sender, ItemTappedEventArgs e)
{
var service = OwnerServicesSlider.SelectedItem as Services;
service.Page.Parent = null;
Navigation.PushAsync(service.Page);
}

Xamarin Forms: System.ObjectDisposedException when setting Focus to an Entry control

I have the following Xamarin Forms page that throws an exception on this line...
The first time this page is loaded, the OnAppearing works fine, sets the focus properly, and doesn't throw an exception.
When I navigate back to this page (ie, logout), OnAppearing is throwing the following...
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Xamarin.Forms.Platform.Android.EntryRenderer'.
What is the best way to set focus to a control on a page in Xamarin Forms?
I'm not sure what is in your XAML, but if you define the x:Name="_entry" on the Entry in XAML, and use that name to access the control directly instead of FindByName, it should work fine.
I try to reproduce your issue at my side, but it works fine and there is no issue when I click Button to navigate another page and coming back. Please take a look my code:
<StackLayout>
<Label
HorizontalOptions="CenterAndExpand"
Text="Welcome to Xamarin.Forms!"
VerticalOptions="CenterAndExpand" />
<Entry
x:Name="UserNameentry"
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand" />
<Button
x:Name="btn1"
Clicked="btn1_Clicked"
HeightRequest="50"
HorizontalOptions="FillAndExpand"
Text="btn1"
VerticalOptions="CenterAndExpand"
WidthRequest="200" />
</StackLayout>
public Page4()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
var usernameentry = FindByName("UserNameentry") as Entry;
usernameentry.Focus();
}
private async void btn1_Clicked(object sender, EventArgs e)
{
Page3 page = new Page3();
await Navigation.PushModalAsync(page);
}
If you still have this issue, please provide some code about xaml here.

Xamarin.Forms: Save File dialog on Xamarin Android

I'm trying to save a file to the device.
The problem is that I'm hardcoding the filename from code behind.
My requirement is to ask the user to save a file with a user defined filename. How can I ask the user to save a file by opening a filesave dialog in Xamarin.Forms?
Have you solved it? Can you post your solution in case?
This question could fit your requirements, it uses this plugin: Xam.plugin.filepicker Xam.Plugin.FilePicker Works fine but can't get file
Here is the easiest popup page using Rg.Plugins.Popup
cs:
public partial class PromptPopup : PopupPage
{
public event EventHandler Oked;
public event EventHandler Canceled;
public PromptPopup(string title, string text)
{
InitializeComponent();
PopupText.Text = text;
PopupTitle.Text = title;
}
private void OnCancel(object sender, EventArgs e)
{
this.Canceled(sender, e);
PopupNavigation.PopAsync(false);
}
private void OnOk(object sender, EventArgs e)
{
this.Oked(sender, e);
PopupNavigation.PopAsync(false);
}
}
its xaml:
<StackLayout VerticalOptions="Center" HorizontalOptions="FillAndExpand" Padding="20, 20, 20, 20">
<StackLayout BackgroundColor="White" Padding="10, 10, 10, 10">
<Label x:Name="PopupTitle" Text="PromptPopupTitle" TextColor="Gray" FontSize="20" HorizontalOptions="Center" />
<ScrollView>
<StackLayout>
<StackLayout Orientation="Horizontal">
<Label x:Name="PopupText"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="Center"
TextColor="Gray"></Label>
</StackLayout>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<Button Text="{i18n:Translate PopupButtonCancel}" Clicked="OnCancel" HorizontalOptions="FillAndExpand"></Button>
<Button Text="{i18n:Translate PopupButtonOk}" Clicked="OnOk" HorizontalOptions="FillAndExpand"></Button>
</StackLayout>
</StackLayout>
</ScrollView>
</StackLayout>
(this page comes from a PopupPage instead of ContentPage)
and you can call it like this
var page = new PromptPopup("title", "text");
page.Oked += Page_OkedLogout;
page.Canceled += Page_CanceledLogout;
await PopupNavigation.PushAsync(page);
further deep support: https://github.com/rotorgames/Rg.Plugins.Popup
You have to implement the file picker yourself, there's no built in way to do that, best to go out to GitHub and look around if that's what you're after.
It sounds to me like you could easily achieve what you're after by just popping a text box, having a user enter a file name, validate the filename with a regex or something and then just saving the file with that file name, you could even just save the file and give them the option to rename the file by listing them all out, but that's all too broad for me to give you an exact implementation, so the best I can do for you is tell you the simple way to do what you're wanting to do.
After selecting file you just open Popup with "Entry" and save file using Entry Text. you can open popup using "Rg.Plugins.Popup"

Get selecteditem from listbox using MVVM

I'm using MVVM in this project, I have a listbox which bind to a collection of Customers. I want to create an event to navigate a detailsPage using id of the elementselected:
<ListBox ItemsSource="{Binding Customers}" x:Name="state_list" SelectionChanged="state_list_SelectionChanged">
<i:Interaction.Triggers>
<i:EventTrigger EventName="selectionchanged">
<cmd:EventToCommand Command="{Binding stateSelectedCommand}" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding nom}" />
<!--TextBlock Text="{Binding LastName}" />
<TextBlock Text="{Binding Text, ElementName=tbCount}" /-->
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I can't figure out how to get the selected item to add it to the uri and then use it to get data. An example or tutorial would be helpful. Thanks :)
I would create a "SelectedCustomer" property in the ViewModel (next to you Customers property) and bind it to the SelectedItem. Then, on the setter of that property you can navigate to your desired page. This way you eliminate the messy events and command.
<ListBox x:Name="state_list
ItemsSource="{Binding Customers}"
SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}">
...
public Customer SelectedCustomer
{
get
{
return _selectedCustomer;
}
set
{
if (value != null)
{
_selectedCustomer = value;
//Navigate to your page here, either with Navigator class or any other mechanism you have in place for changing content on screen
}
}
}
AlexDrenea gives you a good way of binding SelectedItem to a property on your viewmodel. If you are wanting to navigate based on this in an MVVM architecture, I would suggest using messaging to get it done.
I cover this in a blog post I did a while back, but the short summary of doing this within MVVMLight, is to create a Navigator class that sits at the application level.
public class Navigator
{
private PhoneApplicatoinFrame RootFrame;
public Navigator(PhoneApplicationFrame frame)
{
RootFrame = frame;
RegisterMessages();
}
private void RegisterMessages()
{
Messenger.Default.Register<ShowTrackerMessage>(this, ShowTracker);
}
private void ShowTracker(ShowTrackerMessage msg)
{
RootFrame.Navigate(new Uri("/Views/ItemLocationCompassView.xaml", UriKind.RelativeOrAbsolute));
}
}
Then, as part of your application start-up, create it and pass it a reference to your RootFrame:
private static Navigator _navigator;
public static Navigator Nav
{
get { return _navigator; }
}
...
_navigator = new Navigator(this.RootFrame);
Then, you have a couple choices on how you send the Navigation message.
Option 1: In your ViewModel, hook into the PropertyChanged event (part of INotifyPropertyChanged), and send the appropriate message when your SelectedItem property changes.
Option 2: Tie into the SelectionChanged event of your ListBox. I use the MVVMLight's EventToCommand to send that event to a RelayCommand in my ViewModel, then react appropriately to send the message to the Navigator object.
I cover this in more detail at: http://www.smartchitecture.com/?p=27

Databinding with Data Template on ComboBox Select Item using LINQ

I have a little Problem.
A SP give me a several list of URL´s. The Urls are binded on a Combobox.
When I Select an Item, always the Object comes to the Combobox not the Selected Value, see the code below:
<DataTemplate x:Key="Webadressen" DataType="{x:Type src2:GetWebadressenResult}" >
<StackPanel>
<Label Content="{Binding Path=Adresse}" />
</StackPanel>
</DataTemplate>
<ComboBox Width="192" IsEditable="True" Margin="2" Name="Cbox_GDWeb" ItemTemplate="{StaticResource Webadressen}" SelectionChanged="Cbox_GDWeb_SelectionChanged">
private void Cbox_GDWeb_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
GetWebadressenResult test = (GetWebadressenResult)this.Cbox_GDWeb.SelectedValue;
MessageBox.Show(test.Adresse.ToString());
this.Cbox_GDWeb.Text = test.Adresse.ToString(); /* Not Working cause the this Event calls the same Method */
}
Change your ComboBox to this
<ComboBox Width="192" IsEditable="True" Margin="2" Name="Cbox_GDWeb" DisplayMemberPath="Adresse" SelectedValuePath="Adresse" SelectedValue="{Binding Path=Adresse}">
then you wont need the Datatemplate and it will work fine
you also wont need the SelectionChange event to change your selecteditem

Resources