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
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.
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.
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);
}
}
}
}
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.
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");
}
}
}
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.
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
}
}
[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.
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.
And also, your workaround Dmitry does not work for me... sorry...
Let's see what the support thinks about this...
John.
at
yahoo
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.
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...