This is a migrated thread and some comments may be shown as answers.

How to use the picker editor outside dataform

14 Answers 448 Views
DataForm
This is a migrated thread and some comments may be shown as answers.
Carl
Top achievements
Rank 1
Carl asked on 08 Nov 2018, 01:32 PM

Hello,

I'm working on a view where I need to use a couple of picker controls, I can't find any info about a picker control included in Telerik UI for Xamarin, but in the docs I can see the DataForm control includes one, so I would like to use it but without the DataForm itself just the picker in plain XAML, I mean something like:

<telerikInput:RadPicker x:Name="MyRadPicker">

Is this possible?

The buildin xamarin.forms picker works fine but I want to have the same styling abilities in all my controls and using xamarin.forms picker I need to write by hand a custom renderer for just a basic thing like coloring the border.

Attached you can see an image showing how ugly is to use a xamarin.forms picker besides RadEntry, RadCheckBox 

 

 

14 Answers, 1 is accepted

Sort by
0
Lance | Manager Technical Support
Telerik team
answered on 08 Nov 2018, 03:51 PM
Hi Carl,

The DataForm's PickerEditor is not a Xamarin.Forms control, it's a dynamically created native component. Thus, you are not able to instantiate one from Xamarin.Forms manually.


Alternative

Although we don't have a Picker control, the AutoCompleteView might be an option, take a look at the Key Features article where you can see it operate like a ComboBox.


Wrapping Up

If this answers your question, you can let me know by using this thread's "Mark as resolved" button (in the ticket or email). 

Thank you for contacting Support and for choosing UI for Xamarin.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Carl
Top achievements
Rank 1
answered on 08 Nov 2018, 06:58 PM

Thanks for your answer Lance,

Basically what I want to accomplish is a typical "cascading dropdown selection" for States and their Cities, so the user selects in the first picker the city and in the second one the only options available will be the cities that belong to that state, this requires that only one item is permitted to be selected in each control.

Is this possible with the AutoCompleteView? could you please guide me or provide me an example to accomplish this behavior?

P.D Is there any plans to add a Picker/Dropdown to UI for Xamarin?

0
Lance | Manager Technical Support
Telerik team
answered on 08 Nov 2018, 10:30 PM
Hello Carl,

You could get a cascading-like effect by manually populating the next AutoCompleteView (ACV) control when the first one has a selection.

Take a look at Didi's new blog post about the AutoCompleteView. You'll see in the Show / Hide Suggestions section, she discusses how you can use the control in ComboBox-like mode by calling ShowSuggestions when the control is focused. So by shifting forward ItemsSource population and Focus(), you can get a flowing selection behavior.

In your case you can do this following:

1 - Populate the 1st ACV ItemsSource in the page constructor or first load
2 - Call ShowSuggestions() in OnFocus (see this documentation example)
3 - In SuggestionItemSelected event handler, populate a 2nd ACV ItemsSource with you next level of items and then call ACV2.Focus()
4 - Rinse and repeat step 3 for as many levels you need to go down.


Watch this 6 second video of that concept at runtime, you can find the code here in my custom demos repo.



We did have a feature request for a Dropdown/Picker control. The newly released AutoCompleteView control met all the needs of those features requests and the issue was closed. If you find that it doesn't meet your needs, feel free to open a Feature Request for the AutoCompleteView.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items

0
Carl
Top achievements
Rank 1
answered on 09 Nov 2018, 02:29 AM

Hello Lance,

Thanks for your guidance, at first sight it seems it will work for my scenario but I'm using MVVM (with MVVMLight) so I don't really understand how to call the ShowSuggestions() method from ViewModel class.

Could you please guide me thought this using MVVM? 

0
Lance | Manager Technical Support
Telerik team
answered on 09 Nov 2018, 04:50 AM
Hi Carl,

This will depend on how much separation you need between the view and the view model.

Interface (Recommended Approach for MVVM)
If you must stick to 100% separation, then you can use an interface to invoke the method from the view model.

To see an example of this, add my LoginScreenSimple template to a test project so you can see the code (see how to select a template here). In the code behind on the only ContentPage, you'll see I have an interface ()INavigationHandler) that allows the view model to call a method in the view without being tightly coupled. In the view model, I can invoke that interface's method.

Alternative (not recommended for MVVM)
If you don't need to be 100% MVVM and can have a reference to a view object in the view model, you can just pass a reference of the ACVs to the view model:

View Model

public class ViewModel
{
...
    public RadAutoCompleteView CountriesAcv {get;set;}
 
    private void SomeViewModelMethod()
    {
        CountriesACV.Focus();
    }
}

Page 
public partial class MyPage
{
    public MyPage()
    {
        InitializeComponent();
        (BindingContext as ViewModel).CountriesAvc = this.CountriesAcv;
    }
}


EventToCommand

You can use Xamarin.Forms EventToCommandBehavior, the commands will be invoked when the events fire.

Side Note:

You can pass the control instance as the CommandParameter to the command. In this case you would be able to have a reference to the view object without completely breaking MVVM, but you would still need the RadAutoCompleteView type in order to cast the parameter and call ShowSuggestions. So if this view model is in a shared class library, it wold need a reference to the Telerik controls.

For example:

<local:EventToCommandBehavior
    EventName="SuggestionItemSelected"
    Command="{Binding CountryItemSelectedCommand}"
    CommandParameter="{x:Reference StatesAcv}" />

Command delegate
private void ExecuteSuggestedItemSelectedCommand(object parameter)
{
    var acv = parameter as RadAutoCompleteView;
    acv?.ShowSuggestions();
}

I hope this is helpful.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Carl
Top achievements
Rank 1
answered on 09 Nov 2018, 12:59 PM

Hello Lance,

Based on your answer I decided to use the behavior approach because it fits the design I'm following, so at this point I'm able to get a control reference in the OnSuggestionItemSelected event inside my ViewModel class, but I can't get the SuggestionItemSelected reference, in the RadAutoCompleteView object the Token property is empty and I can't find any other property that holds the SuggestionItemSelected, could you please guide me in how to pass it to the ViewModel?

private async void AcvDepartamentos_OnSuggestionItemSelected(object sender)
{
    var acvDepartamento = sender as RadAutoCompleteView;
 
    //How to obtain the SuggestionItemSelected ???
}
0
Lance | Manager Technical Support
Telerik team
answered on 09 Nov 2018, 03:47 PM
Hello Carl,

You can only pass one object as a parameter (unless you made a class that has properties for both and pass that). You would need to either pass a reference to the control or the event args.

You can instead bind to the Text property of the control to a view model property. For example: a string SelectedState property in the VM can be used like this

<telerikInput:RadAutoCompleteView x:Name="StatesAcv" Text="{Binding SelectedState}" ... >

Note
Text will always be a string. If the items source is a collection of complex objects, you would have already set the TextSearchPath. It would be this property that provides the value for Text.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Carl
Top achievements
Rank 1
answered on 09 Nov 2018, 05:15 PM

Hello Lance,

As you mentioned my case is a complex object, basically something like:

public class StateModel
{
    public string Id { get; set; }
 
    public string Name { get; set; }
}

I've set the TextSearchPath to "Name", but to do the internal search of the Cities I need the Id.

After testing setting the Text to a binding property it doesn't work because the value selected (Name) is only visible after the second execution of the "OnSuggestionItemSelected" event, so I think I will need another approach, could you please guide me in how to pass to the VM the SuggestionItemSelectedEventArgs instead of the control itself?

0
Lance | Manager Technical Support
Telerik team
answered on 09 Nov 2018, 06:12 PM
Hello Carl,

To help you further, I've added a new demo page to my repo (see the MvvmPage.xaml). Below are the highlights, but please visit and run the demo to see everything in action because it's a tight concert of action and reaction.

View

The AutoCompleteViews have an EventToCommandBehavior for the Focused event. We do not need to use the SuggestedItemSelected event in this case because the Text property is two-way bound to view model properties.

For example, here is the first AutoCompleteView
 
<telerikInput:RadAutoCompleteView
        x:Name="CountriesAcv"
        ItemsSource="{Binding Countries}"
        Text="{Binding SelectedCountry, Mode=TwoWay}"
        IsEnabled="{Binding IsCountriesAvcEnabled}"
        Watermark="filter countries..."
        SuggestionViewHeight="300">
    <telerikInput:RadAutoCompleteView.Behaviors>
        <behaviors:EventToCommandBehavior
            EventName="Focused"
            Command="{Binding AutoCompleteFocusedCommand}"
            CommandParameter="{x:Reference CountriesAcv}"/>
    </telerikInput:RadAutoCompleteView.Behaviors>
</telerikInput:RadAutoCompleteView>

The command delegate is the following (i give it a tiny delay to ensure the items are ready 

ViewModel

In the view model, I am performing the reactions when the Text property has been set. For example, here's what happens when the Country has been selected:


public string SelectedCountry
{
    get => _selectedCountry;
    set
    {
        if (SetProperty(ref _selectedCountry, value))
        {
            if (!string.IsNullOrEmpty(_selectedCountry))
            {
                // Note: be aware that this is set  even if the user types partial values directly into the box instead of s Suggestion selection
                // This example only checks for a full match in the ItemSource, you may want to take further precaution
                if (Countries.Contains(_selectedCountry))
                {
                    IsStatesAvcEnabled = true;
                    States = new ObservableCollection<string>(Lookups.StatesLookup(_selectedCountry));
                    AutoCompleteService.Focus("StatesAcv");
                }
            }
        }
    }
}


Invoking Focus form the View Model

Notice that last line, this is critical to automatically put the focus on the next AutoCompleteView. If you don't need or want the next one to automatically be opened, you can omit it, but keep in mind that ShowSuggestions will never be called without Focus firing.

The way this works is the view model invokes the interface method and the view will call focus on that element:

public partial class MvvmPage : ContentPage, IAutoCompleteService
{
    public MvvmPage()
    {
        InitializeComponent();
        viewModel.AutoCompleteService = this;
    }
     
    public void Focus(string controlName)
    {
        (this.FindByName<RadAutoCompleteView>(controlName))?.Focus();
    }
}


Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Carl
Top achievements
Rank 1
answered on 10 Nov 2018, 03:54 PM

Hello Lance,

I downloaded the sample from your repo but unfortunately is not working, it's throwing and exception when tap/focus the Countries RadAutoCompleteView.

Pls check the printscreen attached.

P.D.1: I did have some issues restoring the nuget packages for SkiaSharp, it seems their names/ids changed in Nuget

P.D.2: I also upgraded Xamarin.Forms in your projects to the latest version (3.3.0.967583). It's the one I'm using in my project.

0
Lance | Manager Technical Support
Telerik team
answered on 12 Nov 2018, 11:19 PM
Hello Carl,

My apologies, it was working but I didn't test it again after I updated the Telerik NuGet package to the latest release (2018.3.1109). I downgraded to 2018.3.1018, the same version you're using, and it's working as expected again.

Go ahead and get the latest commit, or you can just downgrade the UI for Xamarin package to 2018.3.1018 yourself.

It appears we have a regression in AutoCompleteView when you call ShowSuggestions and the Text property is empty, I have reached out to the dev team to investigate this further and I will be testing other approaches (like setting the bound text properties to string.Empty or "").

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Lance | Manager Technical Support
Telerik team
answered on 12 Nov 2018, 11:27 PM
Hi Carl,

I found the problem, fixed it and updated the project back to 1109. The issue is the bound Text properties need to be initialized as empty strings:



I have updated your Telerik Points for bringing this to my attention.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Carl
Top achievements
Rank 1
answered on 13 Nov 2018, 06:52 PM

Hello Lance,

Thanks for your guidance in this process. Finally I've my view working using an approach sightly different from yours, but based on your tips.

I'm using the Xamarin behavior approach to connect control's events to commands on viewmodel side, basically I'm using the following events:

* Appearing: from Xamarin ContentPage

* Focused: from RadAutoCompleteView

* SuggestionItemSelected: from RadAutoCompleteView

* TextChanged: from RadAutoCompleteView

To avoid manual creation of behaviors I'm using this nuget package that works fine with the current version of Xamarin.Forms.

So, in the Appearing event I'm fetching and setting the item collection of the first RadAutoCompleteView (states). In my case, everything comes from a ASP.NET Core 2 REST API.

Then I just followed your suggested flow using RadAutoCompleteView events:

Focused: Allows me to get a reference of the same control to display the suggestion item list.

SuggestionItemSelected: Allows me to get the current selected item, so I can query my API to get the list of cities using the selected state Id. Here I had to create a custom Converter (IValueConverter) to transform the SuggestionItemSelectedEventArgs to a concrete object.

TextChanged: I used this event to control the current selection status, basically I used a Converter (IValueConverter) to get the values from TextChangedEventArgs and identify if the user removed the selection just comparing if the NewTextValue property is equals to string.empty.

<telerikInput:RadAutoCompleteView x:Name="AcvStates"
                                ItemsSource="{Binding States, Mode=TwoWay}"
                                TextSearchPath="Name"
                                ShowSuggestionView="True"
                                SuggestionViewHeight="100"
                                SearchThreshold="1">
<telerikInput:RadAutoCompleteView.Behaviors>
    <behaviors:EventHandlerBehavior EventName="Focused">
        <behaviors:InvokeCommandAction Command="{Binding AcvStatesOnFocusedCommand}"
                                        CommandParameter="{x:Reference AcvStates}" />
    </behaviors:EventHandlerBehavior>
    <behaviors:EventHandlerBehavior EventName="SuggestionItemSelected">
        <behaviors:InvokeCommandAction Command="{Binding AcvStatesOnSuggestionItemSelectedCommand}"
                                        Converter="{StaticResource StatesSelectedItemConverter}" />
    </behaviors:EventHandlerBehavior>
    <behaviors:EventHandlerBehavior EventName="TextChanged">
        <behaviors:InvokeCommandAction Command="{Binding AcvStatesOnTextChangedCommand}"
                                        Converter="{StaticResource AutoCompleteViewTextChangedConverter}" />
    </behaviors:EventHandlerBehavior>
</telerikInput:RadAutoCompleteView.Behaviors>
</telerikInput:RadAutoCompleteView>

 

Thanks

0
Lance | Manager Technical Support
Telerik team
answered on 13 Nov 2018, 07:13 PM
Hello Carl,

I'm glad I could be of assistance.

Before I conclude this thread, I wanted to make sure that you have a link for the new AutoCompleteView documentation (and not the old control AutoComplete control). Just in case you need to look up features later and don't end up in the wrong place.

If you have any future issues, please start a new thread in the AutoCompleteView forums. We went off on a tangent in the DataForm forums :)

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
DataForm
Asked by
Carl
Top achievements
Rank 1
Answers by
Lance | Manager Technical Support
Telerik team
Carl
Top achievements
Rank 1
Share this question
or