Completed
Last Updated: 07 Feb 2022 09:46 by ADMIN
Release LIB 2022.1.207 (7 Feb 2022)
Simon
Created on: 13 Dec 2021 12:07
Category: AutoCompleteBox
Type: Bug Report
0
RadAutoCompleteBox loses binding to SearchText

Hi,

while integrating a RadAutoCompleteBox into our application, I noticed a problem when binding to its SearchText and SelectedItem properties:

How we use the AutoCompleteBox:
We use the following XAML markup to create the AutoCompleteBox:

<telerik:RadAutoCompleteBox Grid.Column="0" x:Name="UnitSelectionAutoCompleteBox"
AutoCompleteMode="SuggestAppend"
DisplayMemberPath="UnitNumber"
IsEnabled="{Binding UnitNumberEnabled, Mode=OneWay}"
ItemsSource="{Binding UnitSelectionComponent.SearchResults, Mode=OneWay}"
SearchText="{Binding UnitSelectionComponent.UnitNumberSearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding UnitSelectionComponent.SelectedUnit, Mode=TwoWay}"
SelectionMode="Single"
TextSearchMode="Contains"
TextSearchPath="UnitNumber"
WatermarkContent="{StaticResource Loc.UnitNumber}">
</telerik:RadAutoCompleteBox>
All of the bound properties use the INotifyPropertyChanged interface to communicate changes to the ui - there is no code behind, behavior or anything else modifying the properties. We bind to the SearchText in order to dynamically load matching items into the available items list since we are searching through a database table with >100.000 entries.

The problem

Having bound both, the SelectedItem and the SearchText leads to the SearchText binding to break under some circumstances: If UnitSelectionComponent.SelectedUnit is not null when the UI is loaded initially, the SearchText property suddenly contains a hard-coded string instead of the binding we defined. However, there seems to be another required condition I don't know yet since I was not able to reproduce the problem in a simple demo project.

 

I attached three screenshots of our ui and Snoop:

- binding_working shows the control and its SearchText binding in the default state.

- binding_working2 shows the control and its SearchText binding after selecting an item by first typing into the AutoCompleteBox and then selecting an item from the dropdown.

- binding_broken shows the control and its SearchText binding in the broken state: Instead of the binding, SearchText now only contains a string.

 

What I found out so far:

- The issue occurs in two cases:

    1. If I open the module with a preselected item (e.g. by opening a saved document),

    2. If I use a separate selection module to select an item (the selection module is displayed by temprarily switching the DataContext to show the selection UI. When a new item is selected, we set the SelectedUnit and then the DataContext is switched back to show the module ui again, see RadAutoCompleteBox_LostBinding.gif)

- If the SelectedItem is not bound, the issue does not seem to occur.

- Forcing the ui to be reloaded (e.g. by switching to a different module and then back) makes the binding come back.

 

Regards
Simon Müller
Hofmann Fördertechnik GmbH

 

8 comments
ADMIN
Dilyan Traykov
Posted on: 02 Feb 2022 16:08

Hello Simon,

Thank you very much for the provided recording and project.

I'm happy to inform you that I've traced the source of the issue and have already applied a fix in our source code. You should be able to test this with our internal build next Monday 07/02 if the fix successfully passes our QA process.

Please let me know once you manage to give it a try whether the issue is actually resolved in your original application as well. I will be awaiting your reply.

Regards,
Dilyan Traykov
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Simon
Posted on: 27 Jan 2022 14:04

Hello Dilyan,

unfortunately, replacing the RadTabControl with a native TabControl did not change anything either.

However, following my last post, I tried to copy&paste the definition of the AutoCompleteBox to the header section (so outside the TabControl) and it looks like the Bindings are working perfectly there (InsideOutsideTabControlComparison.gif).

I also now managed to reproduce the issue in my sample app. I had to simulate the way we fetch the search items from the database for the issue to occur. I attached the project accordingly.

 

Short summary of all findings I had so far:

- The binding only breaks when the view is loaded while a SelectedItem is already set in the ViewModel. If the SelectedItem is set after the View has been constructed, the Binding does not break.

- The issue only seems to occur if the AutoCompleteBox is located inside the TabControl.

- Not having all items in the AutoCompleteBox's ItemsSource from the very beginning seems to play a role, too.

- Content persistence settings on the TabControl (IsContentPreserved etc.) do not seem to change anything (probably because the whole view is reloaded anyways)

 

Regards
Simon Müller

ADMIN
Dilyan Traykov
Posted on: 20 Jan 2022 08:53

Hello Simon,

This is indeed an interesting difference in behavior based on the layout structure.

To be fair, it is still very hard for me to determine the exact cause of the issue without being able to replicate it at my end.

One more approach for determining its root cause would be to replace the RadTabControl with a native TabControl and see if this has any effect.

Can you please give this a try and let me know how it goes?

Regards,
Dilyan Traykov
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Simon
Posted on: 13 Jan 2022 10:40
Whoops, sorry for the bad formatting in my last comment. I don't know what happened there. In the WYSIWYG editor, everything was looking alright.
Simon
Posted on: 13 Jan 2022 10:38

Hi Dilyan,

I did some further research following your last comment and indeed, the issue seems to be at least partially triggered by the view being unloaded.

  • Setting IsContentPreserved does not help (I actually still had that set on the TabControl due to another issue I encountered recently). However, that was to be excpected since the navigation operates higher up in the Ui tree, causing the whole RadTabControl to be unloaded.
  • But opening the SelectionView in a separate window successfully prevents the issue from occuring.

Curiously, changing tabs within the RadTabControl with SupressSelectedContentTemplateReapplying="False" and  IsContentPreserved="False" (which I thought would also unload the control due to the switching TabPage) does not seem to trigger the issue.

As another side note: This issue only appears in our current UI setup. We once had another version of the affected view where the AutoCompleteBox was located several levels higher up in the tree (but within the same UserControl, so the effect of switching to the SelectionView should theoretically be the same). In that older version of the UI, we never encountered the issue. So it can't really be the navigation process alone that's causing the issue.

Regards
Simon Müller
Hofmann Fördertechnik GmbH

Attached Files:
ADMIN
Dilyan Traykov
Posted on: 10 Jan 2022 10:16

Hi Simon,

Thank you for the extensive research on the issue and the provided files.

It does appear that the cause of the issue is the fact that the view is unloaded, more specifically, the stack trace indicates that the RadDockPanel which is part of the RadTabControl gets measured again.

With this in mind, can you please try the following two troubleshooting steps and let me know if any of them results in any difference:

  • Setting the IsContentPreserved property of the RadTabControl to True:
    <telerik:RadTabControl IsContentPreserved="True">
  • Rather than replacing the Content of the ContentControl in the MainWindow (or its equivalent in your original application), to display the SelectionView in a separate window so as not to unload the content of the MainModuleView.

Please let me know how this goes.

Regards,
Dilyan Traykov
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Simon
Posted on: 03 Jan 2022 11:34

Hi Dilyan,

thank your for the answer and please excuse the late response -  I was away from the office during the holidays.

Thanks to your suggestion, I was able to do some further research on the problem. I attached a zip file containing the following folders:

  • SampleApp: My unsuccessful attempt to reproduce the problem in a very simple environment
  • TypeSingleLetter: Stack trace and visual studio watch when typing a single letter into the AutroCompleteBox for reference.
  • SelectValueFromDropdown: Stack Trace and Visual Studio watch for the "normal" case of selecting an item from the dropdown (via the keyboard since having the breakpoint set to break stops the dropdown from working due to application focus switching an thus auto-hiding the dropdown)
  • SelectValueFromExternalSource !Breaks!: Contains two subfolders, one for each of the two breakpoint hits when setting SelectedItem from our "selection module". Again, stack traces and watch contents are included.
  • UiLayout.png: Shows the xaml tree down to the RadAutoCompleteBox. "ExternalServiceJobRecordingView" is applied via a data template and is switched to the "selection module" by setting a new data context.

This is what I observed by setting a breakpoint at the suggested position:

  • Whenever I use our custom "selection module" to select a new item (in which case the binding breaks), the breakpoint is hit twice instead of once. The first hit seems to be caused by a layout pass and seems to set the SelectedItem's ToString() result ("BusinessLayer.BusinessObjects.Unit.UnitBusinessObject") for the NewValue. The second Hit is then caused by the OnLoaded event of the AutoCompleteBox.
  • in both hits, e.NewValueSource is "Local" instead of "ParentTemplate". Also e.NewEntry.IsExpression is false
  • The hit through the layout pass does not seem to occur in my sample app. So maybe that might be the culprit. However, I don't exactly know what causes the template to be re-loaded in our application, compared to the sample app.

If you need any more info, please let me know.

 

Regards
Simon Müller
Hofmann Fördertechnik GmbH

Attached Files:
ADMIN
Dilyan Traykov
Posted on: 20 Dec 2021 08:54

Hello Simon,

Thank you very much for the provided images, recording, code snippet, and detailed description of the issue.

Although this gives me a good overview of the issue, it is hard for me to determine its exact cause without being able to replicate it at my end. We will also need a project to test the possible fix candidates with.

With this said, if possible, please try to isolate this in a small sample project, or, if you're still are unable to do so, send a project which closely resembles your setup so that I can also try to reproduce the issue at my end.

To troubleshoot in the meantime, you can try to trace the call stack when the SearchText's property is changed to see if there's any difference in the case where the local value is set. To do so, you can create a custom class which overrides the OnPropertyChanged method like so:

    public class CustomRadAutoCompleteBox : RadAutoCompleteBox
 {
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
 {
if (e.Property.Name == "SearchText")
 {
		; // breakpoint here
 }

            base.OnPropertyChanged(e);
 }
    }

You then need to change the definition of the UnitSelectionAutoCompleteBox to this custom class.

Please let me know whether you're able to replicate the issue or if tracing the call stack provides any useful information. I will be awaiting your reply.

Regards,
Dilyan Traykov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.