UWP XAML x:Bind inherited interfaces are not recognized
Asked Answered
H

3

10

When using x:Bind in a UWP XAML application consider the following:

interface IBaseInterface
{
    string A { get; set; }
}
interface ISubInterface : IBaseInterface
{
    string B { get; set; }
}
class ImplementationClass : ISubInterface
{
    public string A { get; set; }
    public string B { get; set; }
}

In the Page class we have the following:

public partial class MainPage : Page
{
    public ISubInterface TheObject = new ImplementationClass { A = "1", B = "2" };
    //All the rest goes here
}

In the MainPage XAML we have the following snippet:

<TextBlock Text={x:Bind Path=TheObject.A}></TextBlock>

Which causes the following compiler error: XamlCompiler error WMC1110: Invalid binding path 'A' : Property 'A' can't be found on type 'ISubInterface'

The following does work however:

<TextBlock Text={x:Bind Path=TheObject.B}></TextBlock>

Does anybody know if it is a known limitation of the UWP XAML platform that inherited interface-properties are not recognized by the compiler? Or should this be considered a bug? Are there any known workarounds?

Help is greatly appreciated. Thanks in advance!

Harakiri answered 4/9, 2015 at 16:37 Comment(1)
Can you try to define TheObject as IBaseInterface rather than ISubInterface and see if the Compiler then accepts TheObject.A?Folie
E
10

Yes, after doing some test and reseach, it seems that inherited interface-properties are not recognized by the compiler when using the X:Bind.

As a workaround we can use the traditional Binding instead of the X:Bind as following:

In the .xaml:

<Grid Name="MyRootGrid">
         <TextBlock Text="{Binding A}"></TextBlock>
</Grid>

In the xaml.cs:

MyGrid.DataContext = TheObject;
Eubanks answered 8/9, 2015 at 7:16 Comment(1)
Thanks for trying and coming to the same conclusion as I did. I did submit a bug via Connect: connect.microsoft.com/VisualStudio/feedback/details/1770944Harakiri
W
1

If you write a class Foo inherited IFoo.

public class Foo : INotifyPropertyChanged, IF1
{
    public Foo(string name)
    {
        _name = name;
    }

    private string _name;
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    string IF1.Name
    {
        get { return _name; }
        set { _name = value; OnPropertyChanged(); }
    }

}

public interface IF1
{
    string Name { set; get; }
}

And when you write a list in page

  public ObservableCollection<Foo> Foo { set; get; } = new ObservableCollection<Foo>()
    {
        new Foo("jlong"){}
    };

How can you bind it in xaml?

I find a way to bind it. You should use x:bind and use Path=(name:interface.xx) to bind it in xaml.

    <ListView ItemsSource="{x:Bind Foo}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:Foo">
                <TextBlock Text="x:Bind Path=(local:IFoo.Name)"></TextBlock>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
Wain answered 23/12, 2017 at 6:49 Comment(0)
B
0

Add the namespace of the base class via a xmlns at the top of the file:

xmlns:base="using:Namespace.Of.Base.Class"
Blabbermouth answered 28/6, 2018 at 16:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.