-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Please add read-only bindable property #75
Comments
Hi @tkouba I tested <!-- CustomLabel.xaml -->
<?xml version="1.0" encoding="utf-8"?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Name="Self"
x:Class="MauiApp1.Controls.CustomLabel">
<VerticalStackLayout BindingContext="{x:Reference Self}">
<Label Text="{Binding Label1}"></Label>
<Label Text="{Binding Label2}"></Label>
</VerticalStackLayout>
</ContentView> // CustomLabel.xaml.cs
using BindableProps;
namespace MauiApp1.Controls;
public partial class CustomLabel : ContentView
{
[BindableProp] private string _label1 = "Label 1 default";
public static readonly BindablePropertyKey Label2PropertyKey =
BindableProperty.CreateReadOnly(nameof(Label2), typeof(string), typeof(CustomLabel), "Label 2 default",
propertyChanged: (bindable, oldValue, newValue) => ((CustomLabel)bindable).Label2 = (string)newValue);
public static readonly BindableProperty Label2Property = Label2PropertyKey.BindableProperty;
public string Label2
{
get => (string)GetValue(Label2Property);
private set
{
OnPropertyChanging(nameof(Label2));
SetValue(Label2PropertyKey, value);
OnPropertyChanged(nameof(Label2));
}
}
public CustomLabel()
{
InitializeComponent();
}
} <!-- 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:controls="clr-namespace:MauiApp1.Controls"
x:Class="MauiApp1.MainPage">
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<controls:CustomLabel Label1="L1" Label2="L2"></controls:CustomLabel>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Expect to see L1 + L2 I would like to know how you make |
Here is one example of using read-only property: public class AxPage : ContentPage
{
public static readonly BindablePropertyKey SizePropertyKey = BindableProperty.CreateReadOnly(nameof(Size), typeof(SizeF), typeof(AxPage), SizeF.Zero);
public static readonly BindableProperty SizeProperty = SizePropertyKey.BindableProperty;
public SizeF Size
{
get => (SizeF)GetValue(SizeProperty);
private set => SetValue(SizePropertyKey, value);
}
protected override void OnSizeAllocated(double width, double height)
{
Size = new SizeF(Convert.ToSingle(width), Convert.ToSingle(height));
base.OnSizeAllocated(width, height);
}
} Property is set only from class itself. I'm using this page descendant for portrait/lanscape detection in model. Edit: Using this page <?xml version="1.0" encoding="utf-8" ?>
<local:AxPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiAppReadOnlyProperty"
x:Class="MauiAppReadOnlyProperty.MainPage"
x:DataType="local:MainViewModel"
Title="{Binding Title}"
Size="{Binding Size}">
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Label Text="{x:Binding Size, Source={x:RelativeSource AncestorType={x:Type local:AxPage}}}"
HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" />
<Label Text="{x:Binding Size}"
HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" />
</VerticalStackLayout>
</ScrollView>
</local:AxPage> code behind: namespace MauiAppReadOnlyProperty
{
public partial class MainPage
{
public MainPage()
{
InitializeComponent();
BindingContext = new MainViewModel();
}
}
} and view model using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace MauiAppReadOnlyProperty
{
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
bool SetValue<T>([NotNullIfNotNull(nameof(newValue))] ref T field, T newValue, Action? onChanged = null, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, newValue))
{
return false;
}
field = newValue;
OnPropertyChanged(propertyName);
onChanged?.Invoke();
return true;
}
string title = "Default title";
public string Title { get => title; set => SetValue(ref title, value); }
SizeF size;
public SizeF Size
{
get => size;
set => SetValue(ref size, value, OnSizeChanged);
}
void OnSizeChanged()
{
if (Size == SizeF.Zero)
{
Title = "Unknown size";
}
else if (Size.Height > Size.Width)
{
Title = "Portrait";
}
else
{
Title = "Landscape";
}
}
}
} |
Hi @tkouba As I see, the prop of Thanks. |
Hi @KafkaWannaFly, I created repo with simple read-only bindable property https://github.com/tkouba/MauiAppReadOnlyProperty. This property is not autogenerated, but it could be. AxPage has read-only property Size. And there are model, which uses this property for porptrait/landscape detection and label on page which shows current size of page. |
* Refactor to reduce duplicate * BindableReadOnlyProp and a simple test case * Abtract test class * Unit test * Config version * Clean up code * Update documentation * Update cicd * Filter test * Upgrade cpdeql version
Hi @tkouba [BindableReadOnlyProp] private SizeF _size = SizeF.Zero; // Value changed but always show {0, 0} on UI
[BindableReadOnlyProp] private bool _isLandscape = false; // Work as expected Can be fixed like this. I guess this was the problem of MAUI itself, have no idea why. [BindableReadOnlyProp(DefaultBindingMode = (int)BindingMode.TwoWay)] private SizeF _size = SizeF.Zero; |
Yes it works. Great work @KafkaWannaFly In MAIU, definition of
So default binding mode for read-only properties is |
@tkouba Thanks for your advice. |
Read-only bindable property is defined like this:
please add an attribute for generating read-only bindable property. It may helps in clean code - no public setter, when you do not want it.
The text was updated successfully, but these errors were encountered: