UWP:如何在 ResourceDictionary 中使用 x:bind?

Oh *_*Dog 3 resourcedictionary uwp xbind

我想在 UWP 中使用 ResourceDictionary 就像我在 WPF 中使用的那样在 WPF 中,我在 ResourceDictionary 文件(*Style.xaml)中执行此操作

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
    xmlns:models="using:NWP.Models">

<Style x:key="MenuContent" TargetType="ContentControl">
    <Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="ContentControl">
            <controls:DockPanel>
                <ItemsControl ItemsSource="{x:Bind How-Can-I-Bind-Collection-Here?}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate x:DataType="models:MenuItemModel">
                            <RadioButton GroupName="MenuItems" IsChecked="{x:Binding IsChecked, Mode=TwoWay}" MinHeight="0" MinWidth="0" Command="{Binding Command}" CommandParameter="{Binding}"/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>

                <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </controls:DockPanel>
        </ControlTemplate>
    </Setter.Value>
</Style>

</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)

然后我可以在我的页面中使用这种样式:

<ContentControl Style="{StaticResource MenuContent}">
    <StackPanel Orientation="Vertical">
        <TextBox/>
        <PasswordBox/>
        <Button Content="Login"/>
    </StackPanel>
</ContentControl>
Run Code Online (Sandbox Code Playgroud)

但是现在,我在如何使用 x:bind 为 ResourceDictionary 中的 ItemsControl 中的 ItemsSource 提供源代码而苦苦挣扎:

<ItemsControl ItemsSource="{x:Bind How-Can-I-Bind-Collection-Here?}">
Run Code Online (Sandbox Code Playgroud)

我的问题是,如何解决这个问题?

Xie*_*ven 5

添加到@Bite 的建议中,我需要为您解释更多信息。在该文件中,它说:

如果您在资源字典中使用 {x:Bind},那么资源字典需要有一个代码隐藏类。

  1. 从文档页面,听起来它可以工作,像任何其他 x:Bind 一样使用支持类作为绑定源,但编译器明确拒绝任何x:Bind in a Style。它根本不受支持。因此,您不能在样式中使用 x:Bind,甚至不能在样式中定义的 DataTemplate 中使用。
  2. 为了使用 ResourceDictionary 中定义的 DataTemplate 中的 x:Bind,您需要为它创建一个类背后的代码。 由于第 1 点,此模板仍必须在任何 Style 之外,但您需要 x:Bind 的支持类才能从 ResourceDictionary 工作。
  3. 要使项目源绑定工作,使用基于 ResourceDictionary 的方法,您需要使用旧版 {Binding} 而不是 {x:Bind}。
  4. 由于我们必须使用旧的 {Binding} 才能使其工作,因此必须通过设置和/或调整 ContentControl 的 DataContext 来自定义项目源。

然后,我做了一个简单的代码示例供您参考:

<ResourceDictionary
x:Class="AppStyle.MenuDictionary"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppStyle"
xmlns:System="using:System">

<Style x:Key="MenuContent" TargetType="ContentControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ContentControl">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <ItemsControl ItemsSource="{Binding MenuItems}" ItemTemplate="{StaticResource MenuItemDataTemplate}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Horizontal"/>
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                    </ItemsControl>
                    <ContentPresenter Grid.Row="1" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<DataTemplate x:Key="MenuItemDataTemplate" x:DataType="System:String">
    <RadioButton GroupName="MenuItems" MinHeight="0" MinWidth="0" Content="{x:Bind}" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

public sealed partial class MenuDictionary : ResourceDictionary
{
    public MenuDictionary()
    {
        this.InitializeComponent();
    }
}
Run Code Online (Sandbox Code Playgroud)
<Page
x:Class="AppStyle.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppStyle"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <local:MenuDictionary/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ContentControl Style="{StaticResource MenuContent}">
        <StackPanel>
            <TextBlock>Test</TextBlock>
            <TextBox />
        </StackPanel>
    </ContentControl>
</Grid>
Run Code Online (Sandbox Code Playgroud)

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        this.DataContext = this;
    }
    public IEnumerable<string> MenuItems => new string[] { "Page Item 1", "Page Item 2", };
}
Run Code Online (Sandbox Code Playgroud)