BindableProps 1.1.1-beta
See the version list below for details.
dotnet add package BindableProps --version 1.1.1-beta
NuGet\Install-Package BindableProps -Version 1.1.1-beta
<PackageReference Include="BindableProps" Version="1.1.1-beta" />
paket add BindableProps --version 1.1.1-beta
#r "nuget: BindableProps, 1.1.1-beta"
// Install BindableProps as a Cake Addin #addin nuget:?package=BindableProps&version=1.1.1-beta&prerelease // Install BindableProps as a Cake Tool #tool nuget:?package=BindableProps&version=1.1.1-beta&prerelease
BindableProps
I spend hours to save your moments.
This library helps you to reduce writing boilerplate code when creating your custom UI components.
Example Usage
Let say you want to create your own text input. Here's how it looks:
namespace MyMauiApp.Controls;
public class TextInput : ContentView
{
public string Text
{
get => (string)GetValue(TextInput.TextProperty);
set => SetValue(TextInput.TextProperty, value);
}
public static readonly BindableProperty TextProperty = BindableProperty.Create(
nameof(Text), typeof(string), typeof(TextInput), string.Empty
);
public string PlaceHolder
{
get => (string)GetValue(TextInput.PlaceHolderProperty);
set => SetValue(TextInput.PlaceHolderProperty, value);
}
public static readonly BindableProperty PlaceHolderProperty = BindableProperty.Create(
nameof(PlaceHolder), typeof(string), typeof(TextInput), string.Empty
);
public TextInput()
{
// Implement your logic
}
}
With BindableProps
, your code will become like this:
using BindableProps;
namespace MyMauiApp.Controls;
// Notice: Your class must be partial class
public partial class TextInput : ContentView
{
[BindableProp]
string text;
[BindableProp]
string placeHolder;
public TextInput()
{
// This piece is same as above
}
}
The real magic happens at Solution Explorer > Dependencies > Analyzers > BindablePropsSG
What you would see in TextInput.g.cs
is the boilerplate code which you had to write. I'll write them for you!
using BindableProps;
namespace MyMauiApp.Controls
{
public partial class TextInput
{
public static readonly BindableProperty TextProperty = BindableProperty.Create(
nameof(Text),
typeof(string),
typeof(TextInput),
default,
BindingMode.Default,
null,
null,
null,
null,
null
);
public string Text
{
get => text;
set
{
text = value;
SetValue(TextInput.TextProperty, text);
}
}
public static readonly BindableProperty PlaceHolderProperty = BindableProperty.Create(
nameof(PlaceHolder),
typeof(string),
typeof(TextInput),
default,
BindingMode.Default,
null,
null,
null,
null,
null
);
public string PlaceHolder
{
get => placeHolder;
set
{
placeHolder = value;
SetValue(TextInput.PlaceHolderProperty, placeHolder);
}
}
}
}
The above example is the minimal amount of code to work. Here is the complete features:
public partial class TextInput : ContentView
{
// Create prop with a few settings
[BindableProp(DefaultBindingMode = ((int)BindingMode.TwoWay))]
string text = "From every time";
// Full setting
[BindableProp(
DefaultBindingMode = ((int)BindingMode.OneWay),
ValidateValueDelegate = nameof(ValidateValue),
PropertyChangedDelegate = nameof(PropertyChangedDelegate),
PropertyChangingDelegate = nameof(PropertyChangingDelegate),
CoerceValueDelegate = nameof(CoerceValueDelegate),
CreateDefaultValueDelegate = nameof(CreateDefaultValueDelegate)
)]
string placeHolder = "Always!";
static bool ValidateValue(BindableObject bindable, object value)
{
return true;
}
static void PropertyChangedDelegate(BindableObject bindable, object oldValue, object newValue)
{
// Do something
}
static void PropertyChangingDelegate(BindableObject bindable, object oldValue, object newValue)
{
// Do something
}
static object CoerceValueDelegate(BindableObject bindable, object value)
{
// Do something
return 0;
}
static object CreateDefaultValueDelegate(BindableObject bindable)
{
// Do something
return string.Empty;
}
}
And the corresponding result would like:
public partial class TextInput
{
public static readonly BindableProperty TextProperty = BindableProperty.Create(
nameof(Text),
typeof(string),
typeof(TextInput),
"From every time",
((int)BindingMode.TwoWay),
null,
null,
null,
null,
null
);
public string Text
{
get => text;
set
{
text = value;
SetValue(TextInput.TextProperty, text);
}
}
public static readonly BindableProperty PlaceHolderProperty = BindableProperty.Create(
nameof(PlaceHolder),
typeof(string),
typeof(TextInput),
"Always!",
((int)BindingMode.OneWay),
ValidateValue,
PropertyChangedDelegate,
PropertyChangingDelegate,
CoerceValueDelegate,
CreateDefaultValueDelegate
);
public string PlaceHolder
{
get => placeHolder;
set
{
placeHolder = value;
SetValue(TextInput.PlaceHolderProperty, placeHolder);
}
}
}
Finally, you can use your component in other page/view like a normal component. For example, at MainPage.xaml
:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:MyMauiApp.ViewModels"
xmlns:controls="clr-namespace:MyMauiApp.Controls"
x:Class="MyMauiApp.MainPage"
x:DataType="vm:MainPageViewModel">
<controls:TextInput PlaceHolder="Say you do"
Text="{Binding MyLoveStory, Mode=TwoWay}" />
</ContentPage>
Roadmap
The BindableProp
along is just not enough for covering all use-cases of BindableProperty
. Planning features:
Attribute | Equivalent/Description |
---|---|
BindableAttachedProp |
BindableProperty.CreateAttached |
BindableAttachedReadOnlyProp |
BindablePropertyKey.CreateAttachedReadOnly |
BindableReadOnlyProp |
BindablePropertyKey.CreateReadOnly |
AllBindableProps |
Put this to your class,<br />Default BindableProp to all field members |
IgnoredProp |
AllBindableProps should ignore this field |
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.4.3 | 298 | 5/13/2024 |
1.4.2 | 89 | 5/13/2024 |
1.4.1 | 86 | 5/11/2024 |
1.4.0 | 136 | 5/4/2024 |
1.3.10 | 275 | 2/12/2024 |
1.3.9 | 378 | 8/19/2023 |
1.3.8 | 230 | 6/24/2023 |
1.3.7 | 287 | 4/17/2023 |
1.3.6 | 181 | 4/16/2023 |
1.3.5 | 186 | 4/11/2023 |
1.3.5-beta | 133 | 4/11/2023 |
1.3.4 | 336 | 1/8/2023 |
1.3.3 | 305 | 1/8/2023 |
1.3.2 | 299 | 1/7/2023 |
1.3.1 | 296 | 1/7/2023 |
1.3.0 | 305 | 1/6/2023 |
1.2.1 | 300 | 1/5/2023 |
1.2.0 | 461 | 7/10/2022 |
1.2.0-beta | 159 | 7/10/2022 |
1.1.9 | 434 | 7/10/2022 |
1.1.8 | 431 | 7/10/2022 |
1.1.8-beta | 180 | 7/9/2022 |
1.1.7-beta | 164 | 7/8/2022 |
1.1.3-beta | 156 | 7/8/2022 |
1.1.2-beta | 156 | 7/8/2022 |
1.1.1-beta | 167 | 7/8/2022 |
1.1.0-beta | 164 | 7/7/2022 |
1.0.7-beta | 177 | 7/5/2022 |
1.0.6-beta | 145 | 7/4/2022 |
1.0.4-beta | 160 | 7/3/2022 |
1.0.3-beta | 165 | 7/3/2022 |
1.0.2-beta | 169 | 7/3/2022 |
1.0.1-beta | 173 | 7/1/2022 |
1.0.0-beta | 163 | 7/1/2022 |