Zebble
  • About Zebble
  • Compare
  • Documentation
  • Themes
  • Plug-ins
  • Contact Us

    • What is Zebble?
    • Structure of a Zebble solution
    • Zebble Designer (UWP)
    • Installing - Introduction
    • Change log
    • Introduction
    • ViewModel development
    • VM.EXE
    • View development
    • Dialogs
    • Lists and Collections
    • Tips and shortcuts
    • List views
    • ViewModel testing
    • Automatic Views
    • View development process
    • Hello World - Core Concepts
    • Layout: Sizing & Positioning
    • Event handling
    • Navigation
    • Alerts, Dialog, Prompt and toast
    • View lifecycle
    • Managing Files & Resources
    • Config & Debugging
    • Forms
    • Page templates
    • Device API
    • Animations
    • Web Api - Part 1 (reading data)
    • Web Api - Part 2 (post and delete)
    • Web Api - Part 3 (server vs client domain model)
    • Gesture events
    • View class
    • Zebble Markup (.zbl files)
    • Data Binding and MVVM
    • Stack class
    • Sizing and positioning
    • Layout examples
    • ScrollView class
    • Page class
    • Styling in Zebble
    • CSS property mapping to Zebble
    • Supported selectors
    • Zebble CSS: Under the hood
    • Inline styling
    • CSS real-time updates
    • Dynamic expressions in CSS
    • Gradient background colours
    • CSS Pseudo-classes support
    • Using Bold and Light Fonts in Zebble
    • Rotation in Zebble
    • Using custom fonts in Zebble
    • Flashing on tap using AutoFlash
    • Button
    • Carousel class
    • Checkbox class
    • DatePicker
    • Drawing class
    • FilePicker class
    • Grid class
    • IconButton class
    • ImageView
    • ItemPicker class
    • ListView & Grid classes
    • OptionsList
    • SearchInput class
    • Slider class
    • Switch class
    • Tabs Class
    • TextInput class
    • TextView
    • TimePicker
    • TreeView
    • Waiting Indicator
    • WebView class (displaying html)
    • C# Methods and Properties Of UI Components
    • Nav.Forward() vs Nav.Go()
    • Passing parameters to the destination page
    • Going Back
    • Showing Popup pages
    • Waiting class
    • Hardware Back button (e.g. Android)
    • NavigationBar class
    • Tabs class
    • Caching (pages)
    • Navigation without event handler
    • Use the Windows version
    • Logging messages for Debugging
    • Debugging Zebble/Plugin
    • Exception handling in Zebble
    • Debugging layout and styles
    • Zebble Device API
    • Device.Screen and orientation (landscape | portrait)
    • Code that should run on a specific platform
    • Using Lamp (aka Flash, LED and Torch)
    • Using Compass (Smooth compass)
    • Using Accelerometer (device angle)
    • Using Gyroscope (device motion speed)
    • How to Vibrate the device?
    • Launching the device browser
    • Finding device model and manufacturer
    • Responding to System events
    • Handling device shake event
    • Permissions
    • Permissions declaration (manifest files)
    • Sharing
    • Prompt for rating the app
    • Finding if Internet connection is available
    • Device messaging (Make a phone call, send SMS or Email)
    • Showing a local notification
    • Copying to Clipboard
    • Accessing device contacts
    • Reading and writing into Gallery (albums)
    • Playing & Recording Audio
    • Cache and temp files and folders
    • C# async / await
    • Understanding Zebble Threading
    • Debugging - the StackTrace problem
    • Not awaiting (running in parallel)
    • Timer (interval / scheduled running)
    • Post-render changes to the UI (dynamic)
    • Introduction of Geo location
    • Map & Location Services
    • Launch directions to a location (external)
    • Getting current Location
    • Tracking user location
    • Device.Media: Taking and picking photos
    • Playing an audio file
    • VideoPlayer class
    • Augmented reality
    • Recording audio
    • Virtual Reality
    • Speech Recognition
    • Recording or picking video
    • Playing remote videos in iOS
    • Text to speech
    • Introduction to the importance of Mobile Testing
    • Why and what to test
    • Testing mobile apps on different devices
    • Testing mobile apps
    • Xamarin Profiler
    • Performance optimization
    • Moving a view to another container at run-time
    • Attaching custom data (tag) to objects
    • Saving a view as image
    • Naming best practices
    • Fastest way to update your nuget package
    • Tips for Clean and Brief code
    • Splash screen and icon generation
    • Advice for passing Approval
    • Options for iOS app distribution
    • Test Release (internal and UAT)
    • Application Icons in IOS
    • Submitting to App Store
    • Releasing to App Store
    • Crash reporting
    • Optimized Release Build
    • Android - Generating an APK for manual installation
    • Payment (subscriptions & in-app purchases)
    • Introduction to push notifications
    • Registration process (App)
    • Push notification setup - iOS
    • Push notification setup - Android
    • Push notification setup - Windows
    • Sending a push message from the web app
    • Introduction
    • Connecting Zebble to Web API
    • Installation
    • Creating an API class
    • GET APIs
    • Calling a GET API (in the mobile app)
    • POST, PUT, PATCH and DELETE APIs
    • Domain Model
    • Web API and Authentication
    • Versioning
    • Uniquely identifying installations (token)
    • Settings file: config.xml
    • Standard Zebble settings
    • Login/Register with Facebook
    • Creating a composite component / plugin
    • Creating a Zebble component using Html and Javascript
    • CustomRenderedView: Third-party native components / plugins
    • Mapbox
    • Naming considerations
    • Random problems?
    • Display Keyboard for Visual Studio Android Emulator
    • iOS goes mad?
    • Configuring a Windows phone for ad-hoc testing
    • Fixing Error DEP0001 : Unexpected Error: -2147009287 while deploying Windows UWP app on device
    • Fixing Error DEP0001 : Unexpected Error: -1988945906 while deploying Windows UWP app on device
    • Unable tp Connect to the Mac agent from Visual Studio
    • Can't connect to the Mac agent from Visual Studio?
    • Choosing the CPU architecture
    • Zebble CLI
    • How to add a Device API to Zebble source?
    • About Automated UI testing
    • What should we test in mobile applications?
    • Creating an Automated UI Test in Zebble



Data Binding and MVVM


Data bindings allow properties of two objects to be linked so that a change in one causes a change in the other. This is a very valuable tool, and while data bindings can be defined entirely in code, Zebble markup provides shortcuts and convenience.

Bindings are used most often to connect the visuals of an app with an underlying data model to enable the MVVM (Model-View-ViewModel) application architecture. 

Bindable<TValue>

Data bindings connect properties of two objects, called the source and the target. The first step is to define a source property in your code-behind class to which your view properties will be bound.

readonly Bindable<string> MyProperty = new Bindable<string>("initial value");Bindable<TValue> is a special type in Zebble which provides the functionality to broadcast changes to one or more subscribers.

To set a value for this property you can either use the Set() method or the Value property. For example:

// .... To change the value anywhere in your code you can use:
MyProperty.Set("New value");
// Or:
MyProperty.Value = "New value";

As soon as a new value is set, all target objects which are bound to this will have their specified property updated as explained below.

Binding a visual property (markup)

In Zebble markup, you can use the @... value prefix syntax to specify a dynamic C# expression as opposed to a literal value.
<TextView Id="MyTextView" Text="@some c# expression..." />If, instead of just @, you use the @{...} syntax then Zebble code generator will understand tha it's a binding scenario and generate the appropriate code to realise the binding. For example:
<TextView Id="MyTextView" Text="@{MyProperty}" />You can see that in the .zebble-generated.cs file Zebble will generate the following C# equivalent line, which is what you can also write manually in case you want to create a binding in code-behind instead of markup:

MyTextView.Bind("Text", () => MyProperty);Alternatively you can use the AddBinding() method of the Bindable object to achieve the same result. This is helpful if you want to create a binding to a non-View object of any type:
MyProperty.AddBinding(MyTextView, "Text");

// Or to benefit from intellisense and compile time checking:
MyProperty.AddBinding(MyTextView, nameof(MyTextView.Text));

Expression-based binding

There are times when you may want to bind the target property to a function of a bindable property (source) as opposed to its direct value.  In those cases you can specify an optional lambda expression to provide the conversion logic.

Example 1:

Let's say you have a Bindable<int> property whose value may change at runtime.

readonly Bindable<int> MyProperty = new Bindable<int>();And you need to display it on the UI but only if it's not Zero. You can achieve that using the following: 

<TextView ... Text="@{MyProperty}" Visible="@{MyProperty, x=> x != 0 }" />

In the above example, the visible property (which is boolean) is being data-bound to a function of the bindable value which is defined as a lambda expression "x => x != 0" and is seperted by a comma from the name of the bindable property "MyProperty".

Example 2:

Let's say you have a DateTime property:

readonly Bindable<DateTime> MyProperty = new Bindable<DateTime>();And you want to display only the Time part on the UI:

<TextView ... Text="@{MyProperty, x=> x.ToShortTimeString()}" />


Did you know?

Background of data binding syntax in .NET

If you have any experience with MVVM implementations such as WPF, Xamarin Forms or UWP, you may know that to define a bindable property in such frameworks you have to write a lot more code, compared to Zebble. In those frameworks to just create a bindable property you have to do all of the following:

  • Your class should implement the INotifyPropertyChanged interface.
  • You should define an event object to broadcast the changes.
  • You should define a property that will invoke the event explicitly. For example
class MyViewModel : INotifyPropertyChanged
{
     DateTime myProperty;
     public event PropertyChangedEventHandler PropertyChanged;

     public DateTime MyProperty
     {
           get => myProperty;
           set
           {
                 if (myProperty == value) return;
                 myProperty = value;
                 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MyProperty)));
           }
      }
}

None of this is required in Zebble as the Bindable<TValue> class will take care of everything. All you need to do is to define a readonly instance of Bindable<...> in your class. This means that in Zebble it's much quicker, cleaner and easier to implement data bindings to implement a full MVVM architecture.




‹
Zebble is a product of Geeks Ltd , a software house based in London, UK. All rights are reserved.

Telephone: +44 (0)845 643 6229

Email: hello@zebble.net

Address: 66a London Road, Morden

Greater London, United Kingdom, SM4 5BE

Privacy Statement
Terms & Conditions
Contact Us