Повторно используемая привязка ContentView для ActivityIndicator - PullRequest
0 голосов
/ 06 июня 2019

У меня есть ActivityIndicator, который у меня есть на нескольких страницах, подобных этому:

<ActivityIndicator HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"
                    Color="DarkBlue" IsVisible="{Binding IsLoading}" IsRunning="{Binding IsLoading}">
</ActivityIndicator>-

Я пытаюсь сделать этот компонент более удобным для повторного использования, создав ContentView, который выглядит следующим образом:

Loading.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="Framework.Controls.Loading" x.Name="Loading">
  <ContentView.Content>
      <ActivityIndicator HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" Color="DarkBlue" 
                         IsVisible="{Binding Source={x:Reference Name=Loading},Path=IsLoading}"
                         IsRunning="{Binding Source={x:Reference Name=Loading},Path=IsLoading}">
      </ActivityIndicator>
    </ContentView.Content>
</ContentView>

Что я пытаюсь использовать с кодом, подобным этому:

<controls:Loading IsLoading="{Binding IsLoading}"></controls:Loading>

У меня проблема в том, что я не уверен, как создать привязку, чтобы я мог установить свойства IsVisible и IsRunning в ActivityIndicator.

Мой код для компонента выглядит следующим образом:

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Loading : ContentView
{
    public static readonly BindableProperty LoadingIndicatorProperty =
        BindableProperty.Create(
            propertyName: nameof(IsLoading), typeof(bool),
            typeof(Loading), default(string), BindingMode.OneWayToSource);

    public bool IsLoading
    {
        get => (bool)GetValue(LoadingIndicatorProperty);
        set => SetValue(LoadingIndicatorProperty, value);
    }

    public Loading()
    {
        InitializeComponent();
    }
}

В текущем коде я получаю ошибки сборки, поэтому что-то здесь явно не так.

Ошибки следующие:

  • В файле Loading.xaml я получаю сообщение для x.Name = Загрузка , что 'Тип x не найден в xmls http://xamarin.com/schemas/2014/forms, а также что присоединяемое свойство 'Name' не найдено в типе 'x'.
  • На странице, где я пытаюсь использовать элемент управления, я получаю сообщение об ошибке: Не найдено ни свойства, ни привязываемого свойства, ни события для 'IsLoading', ни несоответствующего типа между значением и свойством .

Как правильно создать привязку, которая будет применяться к свойствам IsVisible и IsRunning в моем индикаторе активности? И почему компилятору не нравится свойство ContentView 'x.Name'?

Ответы [ 2 ]

1 голос
/ 06 июня 2019

Во-первых, у вас есть опечатка:

Это x:Name, и у вас есть x.Name

Итак, по вашему мнению:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="Framework.Controls.Loading" 
             x:Name="Loading">
  <ContentView.Content>
      <ActivityIndicator HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" Color="DarkBlue" 
                         IsVisible="{Binding IsLoading"
                         IsRunning="{Binding IsLoading">
      </ActivityIndicator>
    </ContentView.Content>
</ContentView>

тогда, в коде позади вы можете просто:

XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Loading : ContentView
{
    public static readonly BindableProperty LoadingIndicatorProperty =
        BindableProperty.Create(
            propertyName: nameof(IsLoading), typeof(bool),
            typeof(Loading), default(string));

    public bool IsLoading
    {
        get => (bool)GetValue(LoadingIndicatorProperty);
        set => SetValue(LoadingIndicatorProperty, value);
    }

    public Loading()
    {
        InitializeComponent();
        BindingContext=this;
    }
}
0 голосов
/ 06 июня 2019

Я создал элемент управления Xamarin.Forms, который делает именно это и многое другое (также обрабатывает ошибки и пустое состояние). Вы можете найти его здесь:

https://github.com/roubachof/Sharpnado.Presentation.Forms#taskloaderview

Сообщение в блоге, объясняющее это в деталях, здесь:

https://www.sharpnado.com/taskloaderview-async-init-made-easy/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...