Reputation: 14002
I'm trying to use compiled bindings in UWP with a simple use case.
In order to make my XAML more readable easy to manage, I've extracted the XAML of a DataTemplate to a UserControl. So I transformed this
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{x:Bind ViewModel.Items}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:ProjectItem">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{x:Bind Name, Mode=OneWay}" />
<TextBlock Text="{x:Bind Description, Mode=OneWay}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Page>
Into this
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{x:Bind ViewModel.Items}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:ProjectItem">
<local:MyUserControl1 />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Page>
<UserControl
x:Class="App1.MyUserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{x:Bind Name}" />
<TextBlock Text="{x:Bind Description}" />
</StackPanel>
</UserControl>
The problem is that it doesn't even compile because x:Bind
doesn't know the context.
How does x:Bind cover this use case?
Upvotes: 2
Views: 1004
Reputation: 439
This could be faster as the DataContext
is casted only once when the Control
is Loaded
.
public ProjectItem ProjectItem { get; private set; }
public MyUserControl1()
{
InitializeComponent();
Loaded += (s, e) =>
{
ProjectItem = (ProjectItem)DataContext;
Bindings.Update();
};
}
Add this if DataContext
change in MainPage
:
DataContextChanged += (s, e) =>
{
ProjectItem = (ProjectItem)DataContext;
Bindings.Update();
};
Based on the answer given by @mm8.
Upvotes: 2
Reputation: 957
I'd suggest create Dependency Property for ProjectItem on your MyUserControl1.xaml.cs
public static readonly DependencyProperty ProjectItemProperty =
DependencyProperty.Register(
nameof(ProjectItem),
typeof(ProjectItem),
typeof(MyUserControl1),
null);
public ProjectItem ProjectItem
{
get => (ProjectItem)GetValue(ProjectItemProperty);
set => SetValue(ProjectItemProperty, value);
}
Then on your XAML, bind the properties of your ProjectItem Dependency Property:
<StackPanel Orientation="Horizontal">
<TextBlock Text="{x:Bind ProjectItem.Name, Mode=OneWay}" />
<TextBlock Text="{x:Bind ProjectItem.Description, Mode=OneWay}" />
</StackPanel>
Then on your MainPage.xaml, pass on the 'ProjectItem' collection item.
<DataTemplate x:DataType="local:ProjectItem">
<local:MyUserControl1 ProjectItem="{x:Bind}"/>
</DataTemplate>
Upvotes: 6
Reputation: 169400
If you use this approach, you could (or rather need to) add a property to MyUserControl1.xaml.cs
that casts the current DataContext
to a ProjectItem
and returns it:
public ProjectItem Item => DataContext as ProjectItem;
public MyUserControl1()
{
InitializeComponent();
DataContextChanged += (s, e) => Bindings.Update();
}
You then bind to this property in the XAML markup:
<StackPanel Orientation="Horizontal">
<TextBlock Text="{x:Bind Item.Name}" />
<TextBlock Text="{x:Bind Item.Description}" />
</StackPanel>
The other option would to use non-compiled {Bindings}
or get rid of MyUserControl1
and revert to the inline DataTemplate
.
Upvotes: 3