x: Bind и UserControls - PullRequest
       22

x: Bind и UserControls

0 голосов
/ 11 октября 2019

Я пытаюсь использовать скомпилированные привязки в UWP с простым вариантом использования.

Чтобы сделать мой XAML более читабельным и простым в управлении, я извлек XAML изDataTemplate для 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 покрывает этот вариант использования?

Ответы [ 2 ]

5 голосов
/ 11 октября 2019

Я бы предложил создать свойство зависимости для ProjectItem на вашем 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);
    }

Затем на вашем 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>
1 голос
/ 11 октября 2019

Если вы используете этот подход, вы можете (или, скорее, должны) добавить свойство к MyUserControl1.xaml.cs, которое преобразует текущий DataContext в ProjectItem и возвращает его:

public ProjectItem Item => DataContext as ProjectItem;

public MyUserControl1()
{
    InitializeComponent();
    DataContextChanged += (s, e) => Bindings.Update();
}

Youзатем свяжите это свойство с разметкой XAML:

<StackPanel Orientation="Horizontal">
    <TextBlock Text="{x:Bind Item.Name}" />
    <TextBlock Text="{x:Bind Item.Description}" />
</StackPanel>

Другой вариант будет использовать некомпилированный {Bindings} или избавиться от MyUserControl1 и вернуться к встроенному DataTemplate.

...