AutoCompleteBox connected to web service is often needed solution, and there are many solutions out there that are bare bone ones, but using such powerful UI framework as Caliburn.Micro is can reap some interesting benefits. So here’s my implementation.
I decided to subclass AutoCompleteBox because i subclass all of the controls i use. I called it AltiAutoCompleteBox.
A new event was added called PopulatingAsync and a new EventArg called PopulatingAsyncEventArgs:
AltiAutoCompleteBox basically just adds another event PopulatingAsync which is called every time Populating event is called:
public partial class AltiAutoCompleteBox:AutoCompleteBox { public event EventHandler<PopulatingAsyncEventArgs> PopulatingAsync; public AltiAutoCompleteBox() { MinimumPopulateDelay = 500; MinimumPrefixLength = 2; FilterMode = AutoCompleteFilterMode.None; // handle the populating event of the associated auto complete box Populating += AssociatedObject_Populating; } private void AssociatedObject_Populating(object sender, PopulatingEventArgs e) { if (PopulatingAsync == null) return; PopulatingAsync(this,new PopulatingAsyncEventArgs(PopulateComplete,e.Parameter)); // cancel the population of the auto complete box e.Cancel = true; } }
PopulatingAsyncEventArgs class is consisted of a Parameter and an action which will be called on ViewModel side when population of items is complete. It basically calls a PopulateComplete Action of AutoCompleteBox
public class PopulatingAsyncEventArgs:EventArgs { public PopulatingAsyncEventArgs(Action complete,string parameter) { PopulateComplete = complete; Parameter = parameter; } public string Parameter { get; private set; } public Action PopulateComplete { get; private set; } }
On viewmodel side you do it something like this:
public void FilterPartners(PopulatingAsyncEventArgs args) { Context.Load(Context.GetPartnersQuery().Where(x => x.Name.Contains(args.Parameter)), x => { PartnerList.Clear(); PartnerList.AddRange(x.Entities); args.PopulateComplete(); } , null); }
And on the view side you hook it up like this:
<AltiControls:AltiAutoCompleteBox Micro:Message.Attach="[Event PopulatingAsync]=[Action FilterPartners($eventArgs)]" SelectedItem="{Binding Partner,Mode=TwoWay}" ItemsSource="{Binding ElementName=ClaimFormUc, Path=DataContext.PartnerList}"/>
The important thing is the Message.Attach part.
And that’s basicall it! Next time you want to use this AutoCompleteBox, you just define the service and hook it up with message.Attach! And it has that yummy bubbling through visual tree built in and all!
Till next time..:)
Leave a Comment