Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UWP XAML x:Bind inherited interfaces are not recognized

Tags:

c#

xaml

uwp

xbind

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!

like image 309
Simon Mattes Avatar asked Sep 04 '15 16:09

Simon Mattes


2 Answers

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;
like image 125
Amy Peng - MSFT Avatar answered Oct 21 '22 23:10

Amy Peng - MSFT


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>
like image 28
lindexi Avatar answered Oct 22 '22 01:10

lindexi