I have a fairly straightforward binding (with {Binding}
, not {x:Bind}
) that is not working:
<ListView
ItemsSource="{x:Bind ViewModel.Items, Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Item">
<StackPanel>
<TextBlock Text="{Binding MyField}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
It compiles, but fails with the error message:
Error: BindingExpression path error: 'MyField' property not found on 'MyNamespace.Item'. BindingExpression: Path='MyField' DataItem='MyNamespace.Item'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')
The same binding works with x:Bind
:
<TextBlock Text="{x:Bind MyField}" />
namespace MyNamespace
{
public class Item : INotifyPropertyChanged
{
public Item()
{
// ...
}
public readonly string MyField = "Foo";
// ...
}
public class MainPageViewModel : INotifyPropertyChanged
{
public MainPageViewModel()
{
// ...
}
private ItemsCollection _itemsCollection = new ItemsCollection();
public ObservableCollection<Item> Items
{
get { return _itemsCollection.Items; }
}
// ...
}
}
Disclaimer: I work for Microsoft.
MyField
is a C# class field, which cannot be bound to with {Binding}
.
To avoid this, change MyField
to a property:
public class Item : INotifyPropertyChanged
{
// ...
private readonly string m_myField = "Foo";
public string MyField { get => m_myField; }
}
Then {Binding MyField}
will work properly.
See this StackOverflow question about the difference between C# fields and properties:
4. Only Properties can be used in Binding Source
Binding Source helps us to decrease the number of lines of code. Fields are not accepted by BindingSource. We should use Properties for that.
This seems to be similar to WPF (which also can't bind on fields).