9 Comments
  •   Posted in: 
  • UWP

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