I have a list that is populated when the view is navigating. Everything loads as expected except with the AutoCompleteView the FilteredItems list starts out empty. Everything is filtered. If I enter a character the FilteredItems then shows what I would expect. With the obsolete AutoComplete this does not occur, the FilteredItems is the complete list as expected. For now sticking with the correctly behaving AutoComplete
Thanks
-Joe
1 Answer, 1 is accepted
Actually the behavior of the RadAutoCompleteView is the correct one - FilteredItems collection is populated when the user starts typing and the filtering logic of the control is executed. There is an issue in the old AutoComplete that caused the FilteredItems to contain the complete list.
Still, you could accomplish the scenario with RadAutoCompleteView with some additional logic. Basically, you would need to use a converter inside the binding of the ListView ItemsSource, so that, when there are no filtered items inside the AutoCompleteView, return the complete list of its items.
I have attached a sample project to show you how this would work, please download it and give it a try.
Regards,
Yana
Progress Telerik
When I used the same Code with <telerikInput:RadAutoComplete the <telerikDataControls:RadListView filled up initially and the filter worked as expected.
Hi Mohit,
Find attached the MainPage.xaml and MainPage.xaml.cs file with the complete implementation. The solution uses the RadAutoCompleteView control and RadListView control
Didi,
Thanks very much! Unfortunately though, I experience the same issue with RadAutoCompleteView vs the obsolete RadAutoComplete control that the others have described.
Both are using the converter as you've shown, but with RadAutoCompleteView the converter is only called once before the ItemsSource collection is created, and then never again.
With the old RadAutoComplete control, the converter is called when the view initially loads AND when the ItemsSource property is set.
Leaving everything else the same, and just switching back to RadAutoComplete in XAML and the converter makes everything work. I've tried adding TwoWay binding mode as well, which didn't help.
Here's my XAML:
First, the converter get's initially called (doesn't really have anything to do at this point though):
Then my ViewModel is called and I hit the FillList( ) method, which sets the ItemsSource property. As soon as the "Forms" collections is set my converter is called again, and everything works.
I took a slightly different approach which is doing what I need, although not using the properties on the RadAutoCompleteView
<input:RadAutoCompleteView Watermark="Search Projects" WatermarkTextColor="DodgerBlue"
x:Name="AutoComplete"
Text="{Binding SearchText, Mode=TwoWay}"
ItemsSource="{Binding ProjectShapes, Mode=TwoWay}"
TextSearchPath="ConstructionMeasure"
CompletionMode="StartsWith"
ShowSuggestionView="False">
<input:RadAutoCompleteView.Behaviors>
<prism:EventToCommandBehavior EventName="FilteredItemsChanged"
Command="{Binding FilteredItemsChangedCommand}"
EventArgsParameterPath="FilteredItems" />
</input:RadAutoCompleteView.Behaviors>
</input:RadAutoCompleteView>
<telerikDataControls:RadListView Grid.Row="1" ItemsSource="{Binding DisplayItems}" >
<telerikDataControls:RadListView.ItemTemplate>
<DataTemplate>
<telerikListView:ListViewTemplateCell>
<!-- Removed -->
</telerikListView:ListViewTemplateCell>
</DataTemplate>
</telerikDataControls:RadListView.ItemTemplate>
<telerikDataControls:RadListView.Behaviors>
<prism:EventToCommandBehavior EventName="ItemTapped"
Command="{Binding ProjectItemTappedCommand}"
EventArgsParameterPath="Item" />
</telerikDataControls:RadListView.Behaviors>
</telerikDataControls:RadListView>
Instead of using the property on the RadAutoCompleteView and the convertor I just used a different ObservableCollection and populate it using the FilteredItemsChanged event handler. This way also to start off I have the DisplayItems be the complete list and then filter as they type ahead
In the ViewModel,
#region FilteredItemsChangedCommand
public ICommand FilteredItemsChangedCommand => new DelegateCommand<IEnumerable>(ExecuteFilteredItemsChanged);
private void ExecuteFilteredItemsChanged(IEnumerable projectShapes)
{
DisplayItems.Clear();
foreach (var projectShape in projectShapes)
{
if (projectShape is BoundaryShapeItem item)
{
DisplayItems.Add(item);
}
}
}
#endregion
Joe,
Thanks! I like your approach and seem to have it setup correctly per your code sample, but for some reason as soon as I type anything into the AutoCompleteView it starts an infinite loop in the ExecuteFilteredItemsChanged function.
How are you declaring your ProjectShapes object that is your AutoCompleteView's ItemsSource in your ViewModel?
If I tinker with how INotifiyPropertyChanged is called on my object it won't do the infinite loop, but it also doesn't seem to TwoWay bind either... I feel like I'm overlooking something silly.
ProjectShapes and DisplayItems are ObservableCollections
// BoundaryShapeItem is model
public ObservableCollection<BoundaryShapeItem> ProjectShapes { get; } = new ObservableCollection<BoundaryShapeItem>();
public ObservableCollection<BoundaryShapeItem> DisplayItems { get; } = new ObservableCollection<BoundaryShapeItem>();
There should be no need to be calling INotifiyPropertyChanged anywhere. An ObservableCollection will fire the required notify events when items are changed and will update the lists accordingly. With an ItemsSource you should instantiate the ObservableCollection once in the VM and then only add and remove items, the framework will handle the rest
Also if you are using Prism (which it looks in your code like you are), you don't need to implement INotifiyPropertyChanged. just inherit from BindableBase
public abstract class ViewModelBase : BindableBase, INavigationAware, IDestructible, IInitialize
and call SetProperty on your Property
public string Title
{
get => _title;
set
{
SetProperty(ref _title, value);
}
}
Joe,
Your solution works beautifully now, thanks so much! I didn't know ObservableCollections behaved in the way you described as we do use Prism BindableBase and setup properties as you showed. Having my ObservableCollection setup the "Prism" way was my issue, and I learned something new, and can cleanup/improve a lot of code. Can't thank you enough!