This is a migrated thread and some comments may be shown as answers.
TextChanged event for combo
13 Answers 159 Views
This is a migrated thread and some comments may be shown as answers.
Kevin Blanton
Top achievements
Rank 1
Kevin Blanton asked on 01 Mar 2010, 07:12 PM
Is there anyway to access the textbox control in an editable combo and attach a textchanged event to it?

We have a combo that is used to assist users with entry, but they do not have to use the drop.  They can select and item or enter what ever they wish.  We would like to use the TextChanged event so that we can capture what a user enters.  We can not use the kippers event because we allow them to past text into it as well.

We have tried using EditableTemplate to add a textbox and attach the TextChange event to it?  We have tried this but we have not found a way to get the button for the combo to show up with it.  If we do this do we have to create our own button to make the combo drop?

Kevin

13 Answers, 1 is accepted

Sort by
0
Valeri Hristov
Telerik team
answered on 01 Mar 2010, 07:20 PM
Hello Kevin,

You could bind the Text property of RadComboBox and this way you will be able to get notifications when it is changed. Please, find attached a simple example, that demonstrates how to create autocomplete text box functionality, that uses Google suggest. To compile the application you will need to use the assemblies from the latest internal build, that can be downloaded here:
http://www.telerik.com/account/downloads/internal-builds.aspx

Best wishes,
Valeri Hristov
the Telerik team

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 Public Issue Tracking system and vote to affect the priority of the items.
0
Kevin Blanton
Top achievements
Rank 1
answered on 05 Mar 2010, 05:49 PM
I appreciate the response.  However, this is not going to work for my situation.

I need to apply some logic before the item is updated in the datasource.

We are allowing the user to enter more data then the field will hold and then splitting it out in to seperate rows if needed.

The textchanged event will solve my issue if I can get access to the textbox control.
0
Valeri Hristov
Telerik team
answered on 08 Mar 2010, 10:59 AM
Hi Kevin,

Unfortunately you cannot easily get access to the TextBox inside RadComboBox. However, the Text property of RadComboBox is changed immediately when the TextBox.Text property changes, e.g. you could replace the TextChanged event with code in the AutocompleteViewModel:

public string Text
{
 get
 {
  return this.text;
 }
 set
 {
  if (this.text != value)
  {
   this.text = value;
   this.OnPropertyChanged("Text");

   // This is the place where you could put the TextChanged handling

   if (value.Length >= this.MinimumTextLength || value.Length == 0)
   {
    this.AutocompleteProvider.GetSuggestions(value);
   }
  }
 }
}

All the best,
Valeri Hristov
the Telerik team

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 Public Issue Tracking system and vote to affect the priority of the items.
0
Dmitry
Top achievements
Rank 1
answered on 01 Nov 2010, 06:33 PM
Valeri,

I have attempted the example you provided.  My AutoCompleteModel is behaving strangely in that when the Suggestions is being changed it triggers the set of public string Text in AutoCompleteModel.cs.  Do you know why this is happening?

The only way I can get around this is by setting a flag to ignore going in the Text set property if the suggestions is being added.  The only problem now is that I dont get the first match as the selected item. 

When I run your sample below in Silverlight4 with the latest beta telerik controls the search result displays then disappears.  I have to click on the dropdown button in order to see the list.  And the items do not auto complete as I thought they would.


Here is the code snippets that I currently have:

private void OnSuggestionsReceived(object sender, SuggestionsReceivedEventArgs e)
        {
            bool emptySelection = string.IsNullOrEmpty(this.Text);

            for (int i = this.Suggestions.Count - 1; i >= 0; i--)
            {
                if (emptySelection || this.Suggestions[i] != this.SelectedItem)
                {
                    suggestions.RemoveAt(i);
                }
            }
            suggestionLock = true;
            foreach (string word in e.Suggestions)
            {
                if (!this.Suggestions.Contains(word))
                {
                    suggestions.Insert(0, word);
                }
            }
            suggestionLock = false;
        }


public string Text
        {
            get
            {
                return this.text;
            }
            set
            {
                if (this.text != value && !suggestionLock)
                {
                    this.text = value;

                    if (value != null)
                    {
                        if (value.Length >= this.MinimumTextLength)
                        {
                            this.AutocompleteProvider.GetSuggestions(value);
                        }
                    }
                    this.OnPropertyChanged("Text");
                }
            }
        }
0
Jonx
Top achievements
Rank 2
answered on 02 Nov 2010, 11:04 PM
Hello Natali,
Dmitry is right... I have the exact same problem...

I can see that you are posting AutocompleteBox samples all around in the forum so I guess you will be able to help us...

Your project is working perfectly but when you convert the project to silverlight 4 and to the latest telerik dlls (2010.2.924.1040 for me) it's not working anymore.

The content of the combobox is constantly cleared. No text stays in it. I can see in my code that when you insert new suggestions : this.Suggestions.Insert(0, word); The Text property gets null assigned...

I've been strugling with that problem all evening and don't see what to do. I'm gonna try dmitry's workaround (thank you for taht).

I absolutely need a working solution ASAP...

Your help would be very much appreciated.

Thanks a lot in advance,
John.
0
Dmitry
Top achievements
Rank 1
answered on 02 Nov 2010, 11:16 PM
John,

I found a better solution.  The main thing I added was BeginInvoke around the select.  And I modified the constructor to pass the RadComboBox when creating this datacontext.

ADEmployeeNameViewModel

 

 

context = new ADEmployeeNameViewModel(comboEmployee);

 

 

 

 

 

 

 

 

<telerik:RadComboBox x:Name="comboEmployee"
                                 EmptyText="Employee Name"
                                 HorizontalAlignment="Stretch"
                                 VerticalAlignment="Center"
                                 Margin="5"
                                 FontSize="10"
                                 CanAutocompleteSelectItems="true"
                                 DisplayMemberPath="{Binding string}"
                                 Text="{Binding Text, Mode=TwoWay}"
                                 IsTextSearchEnabled="True"
                                 IsEditable="True"

                                 SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
                                 ItemsSource="{Binding Suggestions}">
               
                <Grid>
                    <telerik:RadBusyIndicator x:Name="busyIndicator" IsBusy="{Binding IsBusy}">
                    </telerik:RadBusyIndicator>
                </Grid>
            </telerik:RadComboBox>

This will select the appropriate text

textBox.Dispatcher.BeginInvoke(() =>

{

textBox.Select(match.Length, firstMatch.Length);

}


Please let me know if this helps you out.

 

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using ActiveDirectoryServiceReference;
using System;
using System.Windows.Controls;
using Telerik.Windows.Controls;
  
namespace ViewModel
{
    public class ADEmployeeNameViewModel : INotifyPropertyChanged
    {
        private Employee selectedItem;
        private string text;
        private ActiveDirectoryServiceClient client;
        private RadComboBox radComboBox;
        public ADEmployeeNameViewModel(RadComboBox sender)
        {
            radComboBox = sender;
            client = new ActiveDirectoryServiceClient();
            client.GetEmployeesFromContainerCompleted += new EventHandler<GetEmployeesFromContainerCompletedEventArgs>(client_GetEmployeesFromContainerCompleted);
            this.Items = new ObservableCollection<Employee>();
            this.Text = string.Empty;
        }
  
        public bool IsBusy
        {
            get;
            private set;
        }
  
        public Employee SelectedItem
        {
            get
            {
                return this.selectedItem;
            }
            set
            {
                if (this.selectedItem != value)
                {
                    this.selectedItem = value;
                    this.OnPropertyChanged("SelectedItem");
                    //if (this.selectedItem != null)
                    //{
                    //    this.Text = this.selectedItem.Name;
                    //}
                }
            }
        }
  
        private void SelectText(string match, string firstMatch)
        {
            if (radComboBox != null)
            {
                TextBox textBox = radComboBox.ChildrenOfType<TextBox>()[0];
                textBox.Dispatcher.BeginInvoke(() =>
                {
  
                    textBox.Select(match.Length, firstMatch.Length);
                }
                );
            }
        }
  
        private bool ItemNameExists(string name)
        {
            bool result = false;
            foreach (Employee employee in Items)
            {
                result = (employee.Name.ToString().Equals(name, StringComparison.OrdinalIgnoreCase));
                if (result)
                    break;
            }
            return result;
        }
  
        protected void client_GetEmployeesFromContainerCompleted(object sender, ActiveDirectoryServiceReference.GetEmployeesFromContainerCompletedEventArgs e)
        {
            IsBusy = false;
            OnPropertyChanged("IsBusy");
            if (e.Error == null)
            {
                if (!e.Cancelled)
                {
                    string sText = this.Text;
                    bool emptySelection = string.IsNullOrEmpty(sText);
                      
                    for (int i = this.Items.Count - 1; i >= 0; i--)
                    {
                        if (emptySelection || !this.Items[i].Name.StartsWith(sText))
                        {
                            this.Items.RemoveAt(i);
                        }
                    }
                    string firstMatch = "";
                    foreach (Employee emp in e.Result)
                    {
                        firstMatch = emp.Name;
                        if (!ItemNameExists(emp.Name))
                        {
                            this.Items.Add(emp);
                        }
                    }
                    text = sText;
                    OnPropertyChanged("Text");
                    SelectText(sText, firstMatch);
                }
            }
        }
  
  
        public ObservableCollection<Employee> Items
        {
            get;
            private set;
        }
  
        public string Text
        {
            get { return this.text; }
            set
            {
                if (this.text != value)
                {
                    this.text = value;
                    this.OnPropertyChanged("Text");
                      
                    this.GetItems(value);
                }
            }
        }
  
        private void GetItems(string text)
        {
            if (text != null)
            {
                if (text.Length > 1)
                {
                    bool exists = ItemNameExists(text);
                    if (!exists)
                    {
                        IsBusy = true;
                        OnPropertyChanged("IsBusy");
                        client.GetEmployeesFromContainerAsync("Users", text);
                    }
  
                      
                }
            }
        }
  
  
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
  
        private void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
        #endregion
  
    }
}
0
Jonx
Top achievements
Rank 2
answered on 02 Nov 2010, 11:22 PM
Thanks a lot Dmitry...
[edit] your code is formatted correctly... thank you very much...
Also that solution seems more complicated to me. I already have the text selection as my object is bound to the Text property.
But still the sample is not working anymore once you move it to SL4. I'm opening a case ticket. I'll let you know what it gives...
And until then I'll use your first simple workaround ;)
But thanks for the fast response I did not even have the time to test your workaround. I'll let you know what it gives...
John.
0
Jonx
Top achievements
Rank 2
answered on 02 Nov 2010, 11:39 PM
Dmitry? What version of dll are you using?
Becaus while writing the bug report I did remember that I already used that autocomplete code in a previous project and it was working like a charm. The dll version at that time where 2010.2.812.1040.

Now I have the problem with 2010.2.924.1040

this may help the support to find the problem...

Thanks again,
John.
0
Jonx
Top achievements
Rank 2
answered on 03 Nov 2010, 12:17 AM
I confirm, the problem is not present when using version 2010.2.812.1040

And also, your workaround Dmitry does not work for me... sorry...

Let's see what the support thinks about this...

John.
0
Dmitry
Top achievements
Rank 1
answered on 03 Nov 2010, 05:44 AM
I am using the beta release right now.  Which part did not work with that viewModel?  Let me know if I can help if you provide a small sample to dsavy4
at
yahoo
0
Jonx
Top achievements
Rank 2
answered on 03 Nov 2010, 11:45 AM
Hello Dmitry,
Thank you for your help. Your viewmodel is working but it is not answering to my needs.
My need is just to make the AutocompleteCombobox sample work...
I did struggle for hours trying to make it work just to discover that there seems to be a bug as this was working with the previous version.
I did go back to the previous version and will stick there until I get an answer from the support.
I need to focus on my project and don't want to take any risk by using the latest beta...
I'll let you know what it gives...
Thanks again,
John.
0
Jonx
Top achievements
Rank 2
answered on 03 Nov 2010, 02:45 PM
Hello again.
Support confirms this is a know bug and there is no workaround (except going back to previous version).

Please add your vote for it's resolution:
http://www.telerik.com/support/pits.aspx#/public/silverlight/3857

Until then, I'm stuck with previous version...
0
Dmitry
Top achievements
Rank 1
answered on 03 Nov 2010, 02:48 PM
I agree with John and voted for this issue to be fixed. 
Asked by
Kevin Blanton
Top achievements
Rank 1
Answers by
Valeri Hristov
Telerik team
Kevin Blanton
Top achievements
Rank 1
Dmitry
Top achievements
Rank 1
Jonx
Top achievements
Rank 2
Share this question
or