I am tryin to make a "code editor" like control. I want autocomplete for known variables and operators. The RadAutoCompleteBox does almost exactly what I need, it just removes selected items from the list, so I can use every variable or operator only once. Can I disable this feature?
As mentioned, I used the RadAutoCompleteBox in SelectionMode="Multiple" with an ItemSource of a list of all known variables and operators. I just could not find an option to enable multi-multi-select.
the XAML:
<telerik:GridViewDataColumn.CellEditTemplate>
<DataTemplate>
<telerik:RadAutoCompleteBox SelectedItem="{Binding RecipeCondition, Mode=TwoWay}" ItemsSource="{Binding DataContext.ConditionWordList, RelativeSource={RelativeSource AncestorType=telerik:RadGridView}}" SelectionMode="Multiple" AutoCompleteMode="SuggestAppend" TextSearchMode="Contains">
</telerik:GridViewDataColumn.CellEditTemplate>
the ViewModel:
private void initFakeData()
{
string[] operators = { " AND ", " OR ", " NOT ", " + " , " - ", " * ", " / ", "=", "!=", ">", "<", ">=", "<=" };
string[] vars = { "{VAR_1}", "{VAR_2}", "{OTHER_VAR}", "{sumDamnVar}", "{121asdf}", "{121onji}", "{12123}"};
foreach(string oupii in operators)
{
ConditionWordList.Add(oupii);
}
foreach (string variable in vars)
{
ConditionWordList.Add(variable);
}
}
public ObservableCollection<EventWrapper> EventMappingList { get; set; } = new ObservableCollection<EventWrapper>();
public ObservableCollection<string> ConditionWordList{ get; set; } = new ObservableCollection<string>();
I expect the result to still suggest the " AND " operator even after I have typed "{VAR_1} AND {VAR_2}"
So after extensive research of a day I found a simple solution: create a custom filtering.
class ComboBoxLikeFilter : FilteringBehavior, IFilteringBehavior
{
public override IEnumerable<object> FindMatchingItems(string searchText, IList items, IEnumerable<object> escapedItems, string textSearchPath, TextSearchMode textSearchMode)
{
if (string.IsNullOrWhiteSpace(searchText))
{
return ((IEnumerable<object>)items);//.Where(x => !escapedItems.Contains(x));
}
return base.FindMatchingItems(searchText, items, new object[0], textSearchPath, textSearchMode) as IEnumerable<object>;
}
}
and connect this to your AutoCompleteBox:
<telerik:GridViewDataColumn.CellEditTemplate>
<DataTemplate>
<telerik:RadAutoCompleteBox SelectedItem="{Binding RecipeCondition, Mode=TwoWay}" ItemsSource="{Binding DataContext.ConditionWordList, RelativeSource={RelativeSource AncestorType=telerik:RadGridView}}" SelectionMode="Multiple" AutoCompleteMode="SuggestAppend" TextSearchMode="Contains">
<telerik:RadAutoCompleteBox.FilteringBehavior>
<behavior:ComboBoxLikeFilter/>
</telerik:RadAutoCompleteBox.FilteringBehavior>
</telerik:RadAutoCompleteBox>
</telerik:GridViewDataColumn.CellEditTemplate>
This allows you to select items multiple times and get an ObservableCollection. That wouldn't look right after you're finished (obviously telerik just calls the 'ToString' method to show the list) so I made my own
class StringList : ObservableCollection<string>
{
public override string ToString()
{
if(this.Count == 0)
{
return string.Empty;
}
return string.Join(" ", this);
}
}
Hope this helps someone, because that just cost me about 2 days to figure out.