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

RadComboBox shows wrong Text when setting in ViewModel

3 Answers 179 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
JF
Top achievements
Rank 1
JF asked on 11 Dec 2020, 10:23 AM

Hi,

i have a RadComboBox where the ItemsSource is bound to a list of strings, the Text to a String and where IsEditable is true.

When setting the Text (in viewmodel) to a value, which is not included in the list of strings, it shows the "suggested" text (like when i enter it manually in the box), not the text which was set.This occurs when the viewmodel value is set delayed (not in ctor).

Here is a small sample code.

MainWindow.xaml

<Window x:Class="TelerikCombobox.MainWindow"
        xmlns:local="clr-namespace:TelerikCombobox"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel Margin="3">
            <telerik:RadComboBox Text="{Binding SelectedValue, Mode=TwoWay}" ItemsSource="{Binding SuggestedValues}" IsEditable="True"/>
            <TextBlock Text="{Binding SelectedValue, Mode=OneWay}"/>
        </StackPanel>
    </Grid>
</Window>

 

MainWindow.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
 
        this.DataContext = new ViewModel()
        {
            SuggestedValues = new String[] { "100", "200", "300" },
        };
 
        SetValueDelayed();
    }
 
    private async void SetValueDelayed()
    {
        await Task.Delay(2000);
        if (this.DataContext is ViewModel viewModel)
            viewModel.SelectedValue = "3";
    }
}

 

ViewModel.cs

public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        private String m_SelectedValue;
        public String SelectedValue
        {
            get
            {
                return m_SelectedValue;
            }
            set
            {
                m_SelectedValue = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedValue)));
            }
        }
 
        private IEnumerable<String> m_SuggestedValues;
        public IEnumerable<String> SuggestedValues
        {
            get
            {
                return m_SuggestedValues;
            }
            set
            {
                m_SuggestedValues = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SuggestedValues)));
            }
        }
    }

 

After the value "3" is set, the combobox shows 300.

 

Thanks

 

3 Answers, 1 is accepted

Sort by
0
Dilyan Traykov
Telerik team
answered on 15 Dec 2020, 12:44 PM

Hi Jörg,

Thank you very much for the provided code snippets.

With the current implementation of the control, the result you observe is expected and is caused by the IsTextSearchEnabled property of the control which finds the first matching item and sets the Text property to its string representation. You can notice that the same Text is set when you manually type "3" in the TextBox part of the control. The reason why this differs from when you set the value in the constructor is due to the timing of the operations.

One possible approach, in this case, would be to set the IsTextSearchEnabled property to False before setting the SelectedValue property of the viewmodel and bringing it back afterward:

            if (this.DataContext is ViewModel viewModel)
            {
                this.combo.IsTextSearchEnabled = false;
                viewModel.SelectedValue = "3";
                this.combo.IsTextSearchEnabled = true;
            }
Please let me know if such an approach would work for you. If that is not the case, please provide more details on your exact requirement and why you need to use the Text property and I will gladly try to come up with a viable solution for your particular scenario.

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/.

0
JF
Top achievements
Rank 1
answered on 08 Jan 2021, 07:00 AM

Hi,
thanks for your response.

unfortunately this approach wont fit, because the values (a lot) will get set in the viemodel, which has no access to the view (controls).
I'm sorry that my sinppets were misleading. I will attach some updated.

ViewModel.cs

public class ViewModel : INotifyPropertyChanged
   {
       public event PropertyChangedEventHandler PropertyChanged;
 
       private String m_SelectedValue;
       public String SelectedValue
       {
           get
           {
               return m_SelectedValue;
           }
           set
           {
               m_SelectedValue = value;
               PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedValue)));
           }
       }
 
       private IEnumerable<String> m_SuggestedValues;
       public IEnumerable<String> SuggestedValues
       {
           get
           {
               return m_SuggestedValues;
           }
           set
           {
               m_SuggestedValues = value;
               PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SuggestedValues)));
           }
       }
 
       public async void LoadValueDelayed()
       {
           await Task.Delay(2000);
            
           SelectedValue = "3";
       }
   }

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Loaded += MainWindow_Loaded;
        this.DataContext = new ViewModel()
        {
            SuggestedValues = new String[] { "100", "200", "300" },
        };
 
    }
 
    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        if (DataContext is ViewModel viewModel)
            viewModel.LoadValueDelayed();
    }
}

 

Thanks for your effort

0
Dilyan Traykov
Telerik team
answered on 11 Jan 2021, 01:38 PM

Hi JF,

Thank you for the clarification and updated code snippets.

In such a case, I believe you can set the IsTextSearchEnabled property prior to executing the LoadValueDelayed method, await it, and bring it back afterward:

        private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            if (DataContext is ViewModel viewModel)
            {
                this.combo.IsTextSearchEnabled = false;
                await viewModel.LoadValueDelayed();
                this.combo.IsTextSearchEnabled = true;
            }
        }
Please note that for the purpose you will also need to change the return type of the method to Task:
        public async Task LoadValueDelayed()
        {
            await Task.Delay(2000);

            SelectedValue = "3";
        }
I've prepared a small sample project based on these code snippets which seems to achieve the desired result. Please have a look and let me know if the same approach would work in your original application.

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/.

Tags
ComboBox
Asked by
JF
Top achievements
Rank 1
Answers by
Dilyan Traykov
Telerik team
JF
Top achievements
Rank 1
Share this question
or