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!

Michael Hawker - MSFT
  • 1,572
  • 12
  • 18
Simon Mattes
  • 4,866
  • 2
  • 33
  • 53
  • 2
    Can you try to define `TheObject` as `IBaseInterface` rather than `ISubInterface` and see if the Compiler then accepts `TheObject.A`? – dognose Sep 04 '15 at 16:53

3 Answers3

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;
Amy Peng - MSFT
  • 1,902
  • 11
  • 14
  • Thanks for trying and coming to the same conclusion as I did. I did submit a bug via Connect: https://connect.microsoft.com/VisualStudio/feedback/details/1770944 – Simon Mattes Sep 09 '15 at 16:30
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>
lindexi
  • 4,182
  • 3
  • 19
  • 65
0

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

xmlns:base="using:Namespace.Of.Base.Class"
James Esh
  • 2,219
  • 1
  • 24
  • 41