Derik Whittaker

Syndication

News


Using MVVM with the AutoCompleteTextBox in Silverlight 4

The AutoCompleteTextBox is a great tool in Silverlight to allow you to provide relevant information to your users as they are typing as seen below:

image

But there are a few issues with this control

  1. Pretty much every sample on the net uses the code behind to do the heavy lifting and not binding
  2. It will not update the VM text box in real time, which is needed if you want to do on the fly filtering

In this post I will walk you though how to setup your AutoCompleteText  box and we will learn how to do 3 things

  1. Use MVVM to populate and use the control
  2. Use a custom Behavior to allow the property backing the control to be updated in real time
  3. Use a command to trigger background searches on the fly

Using MVVM to populate your control:

In order to populate your AutoCompleteTextBox you will need to bind something to the ItemSource property of the control as such:

ItemsSource="{Binding KeywordSearchSource}"

I am sure you are wondering what the KeywordSearchSource is?  Well it is simple a property which returns a IEnumerable<string>

       public IEnumerable KeywordSearchSource
        {
            get
            {
                return SomeListOfValues.Select( x => x.TextValue );
            }
        }

The next thing you will want to do is setup a property in your view to handle the current value inside the control.  This is needed because we are binding and not using the code behind.  You can do this as below:

Text="{Binding KeywordSearchText, Mode=TwoWay}"

The trick to above is to remember to mark this as being TwoWay or you will not get the results you are expecting

        private string _keywordSearchText;
        public string KeywordSearchText
        {
            get { return _keywordSearchText; }
            set 
            {
                _keywordSearchText = value; 

                NotifyOfPropertyChange(() => KeywordSearchText); 
            }
        }

That does it for the MVVM portion of the setup.  However, you may already know that when binding to a text box the actual binding does not trigger until AFTER the user leaves the control, in many cases this is good but not in our case.  In our case I want to start the filter process as the user types (which is fine as I have all the filter data local, this is NOT fine if I have to do any type of remote call to filter the data as this will cause a bad user experience).

Triggering the binding in real time:

As I stated above the binding of a text box (or autocomplete text box) does not fire until you leave the control and this is not the desired action for us.  In order to get around this we are going to create a custom behavior to allow the text box binding to push the value into our property in real time.

Our custom behavior is going to be called the ImmediateUpdateBehavior and the code can be found below.

    public class ImmediateUpdateBehavior : Behavior
    {
        protected override void OnAttached()
        {
            AssociatedObject.TextChanged += OnTextChanged;
        }

        void OnTextChanged(object sender, RoutedEventArgs e)
        {
            AssociatedObject.GetBindingExpression(AutoCompleteBox.TextProperty).UpdateSource();
        }

        protected override void OnDetaching()
        {
            AssociatedObject.TextChanged -= OnTextChanged;
        }
    }

In the behavior above you can see that all we are pretty much doing is listing for the TextChanged event and forcing the binding to fire.  This is a nice way to do it when developing with MVVM.

Once we have our behavior created we need to attach it to our AutoCompleteTextBox and that can be found below.

image

Triggering the filtering to fire as we type:

I am going to chose to do this via a Command.  I guess you could have the changing value of the property do the same thing but I typically am against doing this as I feel it is hiding the implementation details of the filtering.  I also feel that this can cause unwanted side effects in your code if you are not careful. 

In order to use the command I am going to use the EventTrigger behavior in silverlight to call my command.  You can see this XAML below.

image

In the XAML above you see I am calling the KeywordSearchFilterCommand.  This command will end up calling the code below

        private void KeywordSearchFilter()
        {
	    // Key here is i am simply notifying to rebuind these values and allowing the underlying methods to filter the data
            NotifyOfPropertyChange(() => SomeListOfValues);
            NotifyOfPropertyChange(() => PagedSomeListOfValues);
        }

As you can see from the above I am not doing anything special in the filter method I am simply notifying of property change and letting the various properties doing their own filtering.  The code below is the filtering for my PagedSomeListOfValues property (we are doing client side paging here)

        public ObservableCollection PagedSomeListOfValues
        {
            get
            {
                var skipCount = PageIndex > 0 ? PageIndex * PageSize : 0;
                var takeCount = PageSize;
                var tempItems= SomeListOfValues.Skip(skipCount).Take(takeCount).ToList();

                var observableLinks = new ObservableCollection();
                observableLinks.SetContents(tempItems);

                return observableLinks;
            }
        }

Once you have your 2 properties (list and search field) bound to the AutoCompleteTextBox you are almost there, but not quite.  In order to make this fully work you will want to also you the custom behavior and the filter command.

Hope this helps.

Till next time,


Posted 11-18-2011 4:25 PM by Derik Whittaker
Filed under: ,

[Advertisement]

Comments

Silverlight Development Company India Blog wrote re: Using MVVM with the AutoCompleteTextBox in Silverlight 4
on 11-24-2011 3:35 AM

The VMMV model is very useful tool for Auto Complete Text box For Silverlight Development.

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)