[Bug] .Assign Extension does not work with inherited controls of Label and Entry
danielftz opened this issue · 4 comments
.Assign Extension does not work with inherited controls of Label and Entry.
Stack Trace
I get compiler error:
The type 'Microsoft.Maui.Controls.Label' cannot be used as type parameter 'TBindable' in the generic type or method 'BindableObjectExtensions.Assign<TBindable, TVariable>(TBindable, out TVariable)'. There is no implicit reference conversion from 'Microsoft.Maui.Controls.Label' to 'MyProject.MyLabel'.
Basic Information
- Version with issue: Latest
- Last known good version: 1.0.1
- IDE: VS for mac
- Platform Target Frameworks:
- iOS:
- Android:
- Android Support Library Version:
- Nuget Packages:
- Affected Devices:
Thanks @danielftz! Please include a reproduction sample when you get a chance.
@danielftz I'm not able to reproduce this.
I've opened #136 to add the following Unit Tests that confirm inherited controls are supported for .Assign()
and .Invoke()
:
[Test]
public void AssignCustomLabel()
{
var createdLabel = new CustomLabel().Assign(out Label assignedLabel);
Assert.That(ReferenceEquals(createdLabel, assignedLabel));
}
[Test]
public void InvokeCustomEntry()
{
const string text = nameof(Invoke);
var createdLabel = new CustomEntry().Invoke(l => l.Text = text);
Assert.That(createdLabel.Text, Is.EqualTo(text));
}
class CustomLabel : Label
{
}
class CustomEntry : Entry
{
}
Sorry for the delay. Here is the link to the project. I think the issue for both of Label and Entry is that .TextCenter()
always returns the base class. So if I use .TextCenter().Assign()
that will cause compile error.
Thanks for the reproduction, @danielftz!
This bug can be worked-around by calling .Assign()
first before calling other Maui.Markup extensions methods (example below).
The root cause actually runs a bit deeper, the ITextAlignment
extensions return the Maui base type, eg Label
, instead of the child class, class MyLabel : Label
.
Workaround
public class MainPage : ContentPage
{
private MyLabel lb;
private MyEntry et;
public MainPage()
{
Content = new VerticalStackLayout
{
Children =
{
new MyLabel
{
}.Assign(out lb) // Call `Assign` first
.TextCenter(),
new MyEntry
{
}.Assign(out et) // Call `Assign` first
.TextCenter()
}
};
}
}
public class MyLabel : Label
{
}
public class MyEntry : Entry
{
}