Skip to content
This repository was archived by the owner on Dec 19, 2022. It is now read-only.

Repository files navigation

XF.BindableProperty.Fody

Build StatusNuGet Status

This is an add-in for Fody.

Turns your auto properties into Xamarin.Forms BindableProperties.

Usage

See also Fody usage.

NuGet installation

Install the XF.BindableProperty.Fody NuGet package and update the Fody NuGet package:

PM>Install-Package Fody
PM>Install-Package XF.BindableProperty.Fody

The Install-Package Fody is required since NuGet always defaults to the oldest, and most buggy, version of any dependency.

Add to FodyWeavers.xml

Add <XF.BindableProperty /> to FodyWeavers.xml

<Weavers>
<XF.BindableProperty />
</Weavers>

Overview

What you write:

publicclassFoo:BindableObject{[Bindable]publicstringBar{get;set;}[Bindable(BindingMode=XFBindingMode.OneTime,OwningType=typeof(Color))]publicstringBaz{get;set;}="abc123";[Bindable]publicstringReadonlyBar{get;}="abc123";[Bindable]publicstringReadonlyBaz{get;privateset;}}

What gets compiled:

publicclassFoo:BindableObject{publicstaticreadonlyBindablePropertyBarProperty=BindableProperty.Create(nameof(Bar),typeof(string),typeof(Foo),default(string),BindingMode.OneWay);publicstringBar{get=>(string)GetValue(BarProperty);set=>SetValue(BarProperty,value);}publicstaticreadonlyBindablePropertyBazProperty=BindableProperty.Create(nameof(Baz),typeof(string),typeof(Color),"abc123",BindingMode.OneTime);publicstringBaz{get=>(string)GetValue(BazProperty);set=>SetValue(BazProperty,value);}privatestaticreadonlyBindablePropertyKeyReadonlyBarPropertyKey=BindableProperty.CreateReadOnly(nameof(ReadonlyBar),typeof(string),typeof(Foo),"abc123",BindingMode.OneWay);publicstaticreadonlyBindablePropertyReadonlyBarProperty=ReadonlyBarPropertyKey.BindableProperty;publicstringReadonlyBar{get=>(string)GetValue(ReadonlyBarProperty);}privatestaticreadonlyBindablePropertyKeyReadonlyBazPropertyKey=BindableProperty.CreateReadOnly(nameof(ReadonlyBaz),typeof(string),typeof(Foo),default(string),BindingMode.OneWay);publicstaticreadonlyBindablePropertyReadonlyBazProperty=ReadonlyBazPropertyKey.BindableProperty;publicstringReadonlyBaz{get=>(string)GetValue(ReadonlyBazProperty);privateset=>SetValue(ReadonlyBazPropertyKey,value);}}

Configuration

XF.BindableProperties is highly customizable. Every option which you could normally specify on the BindableProperty.Create method is either implicitly or explicitly configureable.

Callbacks

BindableProperty.Create supports five callbacks.

  • OnPropertyChanged
  • OnPropertyChanging
  • OnCoerceValue
  • OnValidateValue
  • OnCreateDefaultValue

All those callbacks can be implicitly specified in your code:

publicclassFoo:BindableObject{[Bindable]publicstringBar{get;set;}privatestaticvoidOnBarChanged(BindableObjectbindable,objectoldValue,objectnewValue)=>thrownewNotImplementedException();privatestaticvoidOnBarChanging(BindableObjectbindable,objectoldValue,objectnewValue)=>thrownewNotImplementedException();privatestaticobjectOnCoerceBarValue(BindableObjectbindable,objectvalue)=>thrownewNotImplementedException();privatestaticboolOnValidateBarValue(BindableObjectbindable,objectvalue)=>thrownewNotImplementedException();privatestaticobjectOnCreateBarValue(BindableObjectbindable)=>thrownewNotImplementedException();}
  • The callbacks are automatically looked up. The pattern has to be exact, simply replace 'Bar' with your property name.
  • Make sure the method signature and return types exactly match!
  • You can specify any of those callbacks or none at all, they aren't required.

Furthermore, callbacks can be explicitly specified within the attribute:

publicclassFoo:BindableObject{[Bindable(OnPropertyChanged=nameof(PropertyChangedMethod),OnPropertyChanging=nameof(PropertyChangingMethod),OnCoerceValue=nameof(CoerceValueMethod),OnValidateValue=nameof(ValidateValueMethod),OnCreateValue=nameof(CreateValueMethod))]publicstringBar{get;set;}privatestaticvoidPropertyChangedMethod(BindableObjectbindable,objectoldValue,objectnewValue)=>thrownewNotImplementedException();privatestaticvoidPropertyChangingMethod(BindableObjectbindable,objectoldValue,objectnewValue)=>thrownewNotImplementedException();privatestaticobjectCoerceValueMethod(BindableObjectbindable,objectvalue)=>thrownewNotImplementedException();privatestaticboolValidateValueMethod(BindableObjectbindable,objectvalue)=>thrownewNotImplementedException();privatestaticobjectCreateValueMethod(BindableObjectbindable)=>thrownewNotImplementedException();}
  • If the method doesn't exist or any other error, such as signature mismatch, is found, the weaver will throw an exception.
  • The method names can be anything.

Default values

Initializing your property with a normal property initializer is enough to instruct the system with the necessary information. The property initializer will automatically be included in the BindableProperty.Create method call. This approach is constrained by normal field/property initializer rules.

If instead you need more fine grained control or instance level access, you can register (or implicitly) use the 'OnCreateValue' callback.

publicclassFoo:BindableObject{[Bindable]publicstringDefault{get;set;}="abc";[Bindable(OnCreateValue=nameof(CreateValueMethod))]publicstringExplicit{get;set;}privatestaticobjectCreateValueMethod(BindableObjectbindable)=>"abc";//Instance level access throught 'bindable' argument[Bindable]publicstringImplicit{get;set;}privatestaticobjectOnCreateImplicitValue(BindableObjectbindable)=>"abc";//Instance level access throught 'bindable' argument}

Other

  • The binding mode can be controlled via the 'BindingMode' property of the attribute.
  • The concrete owner of the BindableProperty can be controlled via the 'OwningType' property.

Remarks

  • Auto-Properties: Only auto properties are supported. Properties with getter/setter bodies are invalid by definition as Xamarin accesses the BindableProperty directly, not the actual property. As such, custom getter/setter implementations would cause diverging behaviours between XAML and code.
  • OnCoerceValue: Use this callback to constrain inputs instead of a custom getter/setter!
  • OnValidateValue: Use this callback to do any input validation!
  • OnPropertyChanged/OnPropertyChanging: Use those callbacks to notify dependant properties or trigger custom behaviour!
  • OnCreateValue: Use this callback to construct a default value which required instance level access or runtime information!
  • Readonly properties: All properties without a publicly available setter (or none) will automatically be turned into readonly properties following the BindableProperty/BindablePropertyKey pattern.
  • Getters: Properties must have publicly available getters. Private getters, or none at all, arent supported and will throw weaving exceptions!

Roadmap

  • Attached properties
  • Dependant property notification

Icon

Icon designed by Matt Hawdon from The Noun Project.

About

Turns your auto properties into Xamarin.Forms BindableProperties.

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages