9 Comments

If you’re building a custom user control to be used on multiple pages, it may come handy if the control’s functionalities can be easily changed. For example imagine a search grid with a textbox, button and the result list. If you want to use the same control on multiple pages, it may be required that the datasource of the control can be easily configured. One way to handle a scenario like this is to allow the developer customize the behavior on the View Model’s side by using bind to a method. Let’s go through some code:

The user control

image

The idea is to build a user control which can be dropped on to multiple different pages. When the user clicks “Search”, the query is executed on the view model and the result is returned to the user control.

For this we need a Dependency Property of type System.Func. The func takes a string (the search query) and returns a list of objects. This is executed when the user clicks Search. The complete code with the dependency property included is shown below:

    public sealed partial class MyUserControl
    {
        public static readonly DependencyProperty GetQueryResultsCommandProperty =
            DependencyProperty.Register("GetQueryResultsCommand", typeof (Func<string,List<object>>), typeof (MyUserControl), new PropertyMetadata(default(Func<string,List<object>>)));

        public Func<string,List<object>> GetQueryResultsCommand
        {
            get { return (Func<string,List<object>>) GetValue(GetQueryResultsCommandProperty); }
            set { SetValue(GetQueryResultsCommandProperty, value); }
        }

        public MyUserControl()
        {
            this.InitializeComponent();
        }

        private void SearchButtonClick(object sender, RoutedEventArgs e)
        {
            var results = GetQueryResultsCommand.Invoke(this.Keyword.Text);

            ShowResults(results);
        }

        private void ShowResults(List<object> results)
        {
            //
        }
    }

The page

Next thing on the list is a page which contains the user control.

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

        <local:MyUserControl HorizontalAlignment="Center" VerticalAlignment="Center"
                             GetQueryResultsCommand="{Binding GetQueryResults}"/>

    </Grid>

The GetQueryResultsCommand is bound against the view model’s method.

The view model

Last step is to implement the GetQueryResults-method on the view model. The method is implemented as a read-only property of Func<string,List<object>> so it uses the same signature as the dependency property. This can be read as a “method which takes a string as a parameter and returns a list of objects”.

    public class MainPageViewModel
    {
        public Func<string,List<object>> GetQueryResults
        {
            get
            {
                return keyword =>
                           {
                               var result = new List<object>()
                                                {
                                                    "Hello",
                                                    "Query",
                                                    "Results"
                                                };

                               return result;
                           };
            }
        }
    }

And that’s it. When the user clicks the search button, the event handler invokes the method which we have defined on the view model, using bind to method.

image

Comments

Comment by Windows Store Developer Links &#8211; 2013-01-21 | Dan Rigby

[...] DevelopmentSecurity best practices for building Windows Store apps (Windows 8 app developer blog)Bind to Method in WinRT XAML (Mikael Koskinen)Windows 8 GridView, ListView and SnapView (Jesse Liberty)Windows 8 Theme [...]

Comment by White &amp; The Golden Sword cheat

White & The Golden Sword cheat...

Hello, I think your site may be having web browser compatibility problems. Whenever I look at your blog in Safari, it looks fine however when opening in I.E., it''''s got some overlapping issues. I simply wanted to give you a quick heads up! Apart from t...

Comment by You dh

Really? you must be joking. Isn't this like saying you the word xaml begins with x. This is far to basic to blog

You dh
Comment by Filip Skakun

I don't know, it sounds interesting. I have seen binding to ICommand, but that requires implementing a command class, instantiating an object etc. which has commonly been done with RelayCommand or DelegateCommand helpers used with Actions. If a Func works just as well - it fits in quite well with my minimalistic MVVM approach (blog.onedevjob.com/.../). The only problem I see is that the most common control needing command bindings is a Button and it already has a Command property that needs an ICommand, so if you started implementing controls with an alternative command property type - you create compatibility issues in the future...

Comment by on4lpf

What I really would like to see is the XAML that defines the user control

on4lpf