two way data binding example

2 posts, 0 answers
  1. Sadanan
    Sadanan avatar
    1 posts
    Member since:
    Dec 2018

    Posted 13 Aug Link to this post

    With the two-way data binding when the source properties are updated outside of the control, they are still kept in sync with the DataForm editors, enabling you to solve a wide-range of scenarios.

    Above feature is described in Dataform product page however I dont see any example in QSF or SDK Browser, as how two way source binding actually works and what scenarios it can solve. 

    In my scenario, once dataform has been rendered can I use two way binding to update Dataform when my Source model gets updated from async API call.  It would be helpful to see an example for everyone so posting here. 


  2. Lance | Team Lead - US DevTools Support
    Admin
    Lance | Team Lead - US DevTools Support avatar
    1046 posts

    Posted 13 Aug Link to this post

    Hi Sadanan,

    There is nothing special you need to do, it supports it without any configuration. The two-way binding description refers to how we handle the editor's properties internally. The only requirement is that your model's properties invoke PropertyChanged.

    For example, the demo in the RadDataForm Getting Started article is sufficient. The only thing you need is a reference to the object being used for the Source. In the case of that example, since the XAML doesn't have an x:Name for the SourceItem, you would just do this to change a value:

    (dataForm.Source as SourceItem).Name = "New Name";

    To make the example simpler so we can focus on the relevant part, I've written a new demo. 

    Demo

    You can find the runnable project attached, click the button to increase the inventory value represented by the InStock property. You will see that while updating the InStock property, the DataForm shows those changes in real time.

    For your convenience, here is the relevant code:

    MainPage.xaml

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:d="http://xamarin.com/schemas/2014/forms/design"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:input="clr-namespace:Telerik.XamarinForms.Input;assembly=Telerik.XamarinForms.Input"
                 mc:Ignorable="d"
                 x:Class="TwoWayBindingTest.MainPage">
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
    
            <input:RadDataForm x:Name="DataForm"/>
    
            <Button Text="Increase Inventory"
                    Clicked="Button_OnClicked"
                    Margin="10"
                    Grid.Row="1"/>
        </Grid>
    
    </ContentPage>

    MainPage.xaml.cs

    using System.ComponentModel;
    using Telerik.XamarinForms.Input;
    using Xamarin.Forms;
    
    namespace TwoWayBindingTest
    {
        [DesignTimeVisible(false)]
        public partial class MainPage : ContentPage
        {
            private Book currentBook;
    
            public MainPage()
            {
                InitializeComponent();
    
                currentBook = new Book
                {
                    Title = "The Martian",
                    Price = 19.99,
                    InStock = 43
                };
    
                DataForm.Source = currentBook;
    
                DataForm.RegisterEditor(nameof(Book.Title), EditorType.TextEditor);
                DataForm.RegisterEditor(nameof(Book.Price), EditorType.DecimalEditor);
                DataForm.RegisterEditor(nameof(Book.InStock), EditorType.IntegerEditor);
            }
    
            private void Button_OnClicked(object sender, EventArgs e)
            {
                currentBook.InStock = currentBook.InStock + 1;
            }
        }
    }

    Book.cs

    using Telerik.XamarinForms.Common;
    using Telerik.XamarinForms.Common.DataAnnotations;
    
    namespace TwoWayBindingTest
    {
        public class Book : NotifyPropertyChangedBase
        {
            private string title;
            private double price;
            private int inStock;
    
            [DisplayOptions(Header = "Title")]
            public string Title
            {
                get => title;
                set => UpdateValue(ref title, value);
            }
    
            [DisplayOptions(Header = "Price")]
            public double Price
            {
                get => price;
                set => UpdateValue(ref price, value);
            }
    
            [DisplayOptions(Header = "Inventory")]
            public int InStock
            {
                get => inStock;
                set => UpdateValue(ref inStock, value);
            }
        }
    }

    I hope this helps clarify how the DataForm identifies property changes.

    Side Note

    Since you mentioned that you may be updating values from the result of async calls, be sure that the code updates the property values on the UI thread. If the Task isn't returning to the same thread context, you will want to use Device.BeginInvoke to marshal the call back to the UI thread. This is the same as you'd do for any UI bound property.

    For example, here's modified version of the demo with a simulated network call that doesn't return to the UI thread:

    private async void Button_OnClicked(object sender, EventArgs e)
    {
        await SomeApiCallAsync().ConfigureAwait(false);
    }
    
    private async Task SomeApiCallAsync()
    {
        // Simulating some long running network based work
        await Task.Delay(250);
    
        // Because the task isn't returning result to UI thread, marshall this to the UI thread using BeginInvoke
        Device.BeginInvokeOnMainThread(() =>
        {
            currentBook.InStock = currentBook.InStock + 1;
        });
    }

    Regards, Lance | Technical Support Engineer, Principal
    Progress Telerik

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top