无法绑定IsBusy属性

时间:2016-09-17 19:31:23

标签: xaml xamarin xamarin.forms

我的页面带有活动指示符,代码如下:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.ClientSearch" Title="Search">
  <ContentPage.Content>
    <StackLayout Orientation="Vertical">
      <StackLayout.Children>
        <SearchBar x:Name="txtSearchClient" TextChanged="OnTextChanged"></SearchBar>
        <ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="{Binding IsBusy}" x:Name="indicadorCargando" />
        <ListView x:Name="lstClients"></ListView>
      </StackLayout.Children>
    </StackLayout>  
  </ContentPage.Content>
</ContentPage>

在与此xaml关联的分部类中,我有:

namespace MyApp
{
    public partial class ClientSearch: ContentPage
    {
        public BusquedaClientes()
        {
            InitializeComponent();
        }

        async void OnTextChanged(object sender, TextChangedEventArgs e)
        {

            if (this.txtSearchClient.Text.Length >= 3)
            {
                var list_clients = App.ClientsManager.GetTasksAsync(txtSearchClient.Text);
                this.IsBusy = true;

                var template = new DataTemplate(typeof(TextCell));

                template.SetBinding(TextCell.DetailProperty, "name_ct");
                template.SetBinding(TextCell.TextProperty, "cod_ct");

                lstClients.ItemTemplate = template;
                lstClients.ItemsSource = await list_clients;

                this.IsBusy = false;

            }
        }
    }
}

如您所见,this.IsBusy正在设置Page属性,因此尝试绑定到XAML中的该属性。不幸的是,它不起作用:

<ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="{Binding IsBusy}" x:Name="indicadorCargando" />

如何将ActivityIndi​​cator的值绑定到IsBusy页面属性? 我已经知道设置这样的值:

this.IsBusy = true;
indicadorCargando.IsVisible=true; 
indicadorCargando.IsRunning=true;

但我不想这样做,我想设置一个值而不是三个。

3 个答案:

答案 0 :(得分:1)

你当然可以选择单独的视图模型,这不是一个坏主意。但是对于特定的问题,看起来你并没有在任何地方设置BindingContext,因此它不会获得你想要的IsBusy属性。

我还没有尝试将控件的BindingContext设置为自身,但是这样的事情应该有效:

<ActivityIndicator
  IsVisible="{Binding IsBusy}"
  IsRunning="{Binding IsBusy}"
  x:Name="indicadorCargando"
  BindingContext="{x:Reference indicadorCargando}" />

答案 1 :(得分:0)

以下是我将如何重写它:

public class ClientSearch : ContentPage
    {
        public ClientSearch()
        {
            BindingContext = new ClientSearchViewModel();
            var stack = new StackLayout();
            var searchBar = new SearchBar();
            searchBar.SetBinding<ClientSearchViewModel>(SearchBar.TextProperty, x => x.Text);
            var actInd = new ActivityIndicator();
            actInd.SetBinding<ClientSearchViewModel>(ActivityIndicator.IsVisibleProperty, x => x.IsBusy);
            actInd.SetBinding<ClientSearchViewModel>(ActivityIndicator.IsRunningProperty, x => x.IsBusy);
            var lv = new ListView
            {
                ItemTemplate = new DataTemplate(() =>
                {
                    var txtCell = new TextCell();
                    txtCell.SetBinding<MyItemModel>(TextCell.TextProperty, x => x.Name_Ct);
                    txtCell.SetBinding<MyItemModel>(TextCell.TextProperty, x => x.Cod_Ct);
                    return txtCell;
                })
            };
            lv.SetBinding<ClientSearchViewModel>(ListView.ItemsSourceProperty, x => x.items);
            stack.Children.Add(searchBar);
            stack.Children.Add(actInd);
            stack.Children.Add(lv);
            Content = stack;
        }
    }

    public class ClientSearchViewModel : BaseViewModel
    {
        public string Text { get; set; }
        public bool IsBusy { get; set; }
        public IEnumerable<MyItemModel> items { get; set; }

        protected override async void OnPropertyChanged(string propertyName = null)
        {
            if (propertyName != nameof(Text) || Text.Length < 3) return;
            IsBusy = true;
            items = await App.ClientsManager.GetTasksAsync(Text);
            IsBusy = false;
        }
    }

    [ImplementPropertyChanged]
    public abstract class BaseViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

答案 2 :(得分:0)

您需要为您的网页命名(x:Name="myPage"),然后使用{Binding Source={x:Reference myPage}, Path=IsBusy}对ActivityIndi​​cator的IsVisibleIsRunning值的引用声明绑定。有关this answer的更多信息。