x:绑定和用户控件
Posted
技术标签:
【中文标题】x:绑定和用户控件【英文标题】:x:Bind and UserControls 【发布时间】:2020-02-09 00:47:15 【问题描述】:我正在尝试通过一个简单的用例在 UWP 中使用已编译的绑定。
为了使我的 XAML 更具可读性且易于管理,我已将 DataTemplate 的 XAML 提取到 UserControl。所以我改变了这个
MainPage.xaml
<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>
进入这个
MainPage.xaml
<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>
MyUserControl1.xaml
<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>
问题在于它甚至无法编译,因为x:Bind
不知道上下文。
x:Bind 如何覆盖这个用例?
【问题讨论】:
使用x:Bind
绑定到框架元素(代码隐藏类),它需要在编译时固定所有类型。在这种情况下为什么还要使用x:Bind
?
@Çöđěxěŕ:为什么?例如编译时安全。
@mm8 好点,因为用户已经看到...
【参考方案1】:
我建议在 MyUserControl1.xaml.cs 上为 ProjectItem 创建依赖属性
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);
然后在您的 XAML 上,绑定您的 ProjectItem 依赖属性的属性:
<StackPanel Orientation="Horizontal">
<TextBlock Text="x:Bind ProjectItem.Name, Mode=OneWay" />
<TextBlock Text="x:Bind ProjectItem.Description, Mode=OneWay" />
</StackPanel>
然后在您的 MainPage.xaml 上,传递“ProjectItem”集合项。
<DataTemplate x:DataType="local:ProjectItem">
<local:MyUserControl1 ProjectItem="x:Bind"/>
</DataTemplate>
【讨论】:
如果ProjectItem
有 10 个属性怎么办?那么你需要创建 10 个依赖属性。因此,我们可以尝试创建一个依赖属性为ProjectItem
?只是一个建议。【参考方案2】:
如果您使用这种方法,您可以(或者说需要)向MyUserControl1.xaml.cs
添加一个属性,将当前的DataContext
转换为ProjectItem
并返回它:
public ProjectItem Item => DataContext as ProjectItem;
public MyUserControl1()
InitializeComponent();
DataContextChanged += (s, e) => Bindings.Update();
然后在 XAML 标记中绑定到该属性:
<StackPanel Orientation="Horizontal">
<TextBlock Text="x:Bind Item.Name" />
<TextBlock Text="x:Bind Item.Description" />
</StackPanel>
另一种选择是使用未编译的Bindings
或删除MyUserControl1
并恢复为内联DataTemplate
。
【讨论】:
以上是关于x:绑定和用户控件的主要内容,如果未能解决你的问题,请参考以下文章