I am trying to directly bind to a model (similar to the situation here), instead of the property on that model, but it is not working. I previously asked a question about this, and the answer had worked in UWP. I am now working in WinUI3 (packaged UWP) and am not sure if the same solution applies.
I have a class:
public class Message
{
public string Title { get; set; }
public string Content { get; set; }
}
I have a UserControl that displays that class:
public sealed partial class MessageControl : UserControl
{
/// <summary>
/// The message to display.
/// </summary>
public Message Message { get; set; }
public MessageControl()
{
this.InitializeComponent();
}
}
With XAML:
<UserControl
x:Class="MessageClient.Controls.EmailControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MessageClient.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<StackPanel>
<!-- Displays the title of the message. -->
<TextBlock Name="HeaderTextBlock"
Text="{x:Bind Message.Title, Mode=OneWay}"></TextBlock>
<!-- Displays the content of the message. -->
<TextBlock Name="ContentPreviewTextBlock"
Text="{x:Bind Message.Content, Mode=OneWay}"></TextBlock>
</StackPanel>
</Grid>
</UserControl>
Now, I have a Window I am displaying that control on, inside of a list view:
<Window
x:Class="MessageClient.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:EmailClient"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:MessageClient.Controls" xmlns:models="using:MessageClient.Models"
mc:Ignorable="d">
<Grid>
<!-- The list of messages. -->
<ListView x:Name="MessagesListView"
ItemsSource="{x:Bind Messages}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:Message">
<controls:MessageControl Margin="5"
Message="{x:Bind Mode=OneWay}"></controls:MessageControl>
<!-- TEST 1 -->
<!--<TextBlock Text="{x:Bind Title}"></TextBlock>-->
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!-- TEST 2 -->
<!--<controls:MessageControl Message="{x:Bind TestMessage, Mode=OneWay}"></controls:MessageControl>-->
</Grid>
</Window>
And the code behind for the Window is:
public sealed partial class MainWindow : Window
{
public ObservableCollection<Message> Messages;
public Message TestMessage;
public MainWindow()
{
this.InitializeComponent();
// Populate the test message.
this.PopulateTestMessages();
}
private void PopulateTestMessages()
{
// The TestDataGenerator just returns a staticaly defined list of test messages.
this.Messages = new ObservableCollection<Message>(TestDataGenerator.GetTestMessages(10));
this.TestMessage = this.Messages.First();
}
}
When I run this code (which compiles and runs), I get a window with the expected number of items in the ListView
(10), but they are all blank. There are also no XAML binding failures being reported (via the new feature in Visual Studio 2022). In an attempt to investigate this, I added in a textblock inside of the listview (denoted as TEST 1 in the comments) bound to the Title
property of the Message
. This worked as expected, displaying the correct titles for the 10 messages. I then added a single MessageControl
to the Window
outside of the ListView
(denoted as TEST 2 in the comments) bound to a single Message
property on the Window
. This also worked exactly as expected.
Am I missing something? Why does the specific case of binding to a model directly (as opposed to a property on that model - i.e. a binding with no path) not work, when the data is there and works with other binding configurations?