问题描述
我正在根据以下答案将图像异步加载到我的Listview中:
I'm loading images async into my Listview according to this answer: Xamarin - Asynchronous data binding
我想在页面从网络加载数据时显示一个ActivityIndicator,但无法弄清楚如何绑定它的可视性
I'd like to display a ActivityIndicator while the page is loading the data from the web, but cannot figure out how to bind the visibility it to the task, so that it disappears when the task is done loading..
我已经在ViewModel中创建了isLoading bool变量。
I've created a isLoading bool variable in my ViewModel.
我在ViewModel中以这种方式尝试过,但是它不起作用:
I tried it this way in my ViewModel, but It's not working:
isLoading = true;
GetImagesCommand = new Command(async () => await DoGetImagesCommand(pCode, gCode, gUrl));
isLoading = false;
我也尝试在Task中进行设置,但是isLoading始终为false。.
I also tried setting it in the Task, but isLoading is always false..
private async Task DoGetImagesCommand(string pCode, string gCode, string gUrl)
{
isLoading = true;
var images = await _galleryService.GetImageList(pCode, gCode, gUrl);
foreach (var image in images)
Galleries.Add(image);
isLoading = false;
}
我的Xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:GalShare.ViewModel"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" xmlns:forms="clr-namespace:RedCorners.Forms;assembly=RedCorners.Forms"
mc:Ignorable="d"
x:Class="GalShare.Views.Gallery">
<ContentPage.Content>
<AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1">
<CollectionView ItemsSource="{Binding Galleries}" x:Name="MyCollection" SelectionMode="Single" SelectionChanged="CollectionView_SelectionChanged">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ContentView Padding="1">
<forms:Frame2 CornerRadius="15"
HasShadow="True"
ShadowRadius="8"
Padding="0">
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="LightGray" Padding="2">
<ffimageloading:CachedImage x:Name="myImage" Source="{Binding ThumbUrl}" Aspect="AspectFit" CacheDuration="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" DownsampleToViewSize="False"></ffimageloading:CachedImage>
<Label x:Name="Picname" Text="{Binding ImageName}" IsVisible="{Binding showName}" VerticalOptions="StartAndExpand" VerticalTextAlignment="Center" HorizontalTextAlignment="Center" ></Label>
</StackLayout>
</forms:Frame2>
</ContentView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
<StackLayout IsVisible="{Binding isLoading}" x:Name="LoadingLayout" Padding="12"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1">
<ActivityIndicator />
<Label Text="Loading gallery..." HorizontalOptions="Center" TextColor="Black"/>
</StackLayout>
</AbsoluteLayout>
</ContentPage.Content>
我的ViewModel:
my ViewModel:
namespace GalShare.ViewModel
{
class GalleryViewModel
{
public string pCode { get; set; }
public string gCode { get; set; }
public string gUrl { get; set; }
public bool isLoading { get; set; }
public bool showname { get; set; }
public ObservableCollection<picdata> Galleries { get; } = new ObservableCollection<picdata>();
public ICommand GetImagesCommand { get; }
private GalleryService _galleryService;
public GalleryViewModel(string pCode, string gCode, string gUrl, string showName)
{
this.pCode = pCode;
this.gCode = gCode;
this.gUrl = gUrl;
_galleryService = new GalleryService();
GetImagesCommand = new Command(async () => DoGetImagesCommand(pCode, gCode, gUrl, showName));
}
private async Task DoGetImagesCommand(string pCode, string gCode, string gUrl, string showName)
{
isLoading = true;
var images = await _galleryService.GetImageList(pCode, gCode, gUrl, showName);
foreach (var image in images)
Galleries.Add(image);
isLoading = false;
}
}
}
图库服务:
class GalleryService
{
private HttpClient _httpClient;
public GalleryService()
{
_httpClient = new HttpClient();
}
public async Task<IEnumerable<picdata>> GetImageList(string pCode, string gCode, string gUrl, string showName)
{
var response = await _httpClient.GetAsync(gUrl).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
// var json = response.Content.GetStringAsync().ConfigureAwait(false);
var deserialized = JsonConvert.DeserializeObject<JsonTxt>(json);
bool shownametemp;
if (showName == "1")
{
shownametemp = true;
}
else
{
shownametemp = false;
}
var images = new List<picdata>();
foreach (var img in deserialized.Files)
{
images.Add(new picdata()
{
ImageName = img.file,
BaseUrl = deserialized.Settings.Path.ToString(),
ThumbUrl = deserialized.Settings.Path.ToString() + "thumbs/" + img.file,
showname = shownametemp
}) ;
}
return images;
}
return new picdata[0]; // return empty set
}
}
推荐答案
您应该这样使用 ActivityIndicator
<ActivityIndicator AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
AbsoluteLayout.LayoutFlags="All"
IsVisible="{Binding IsBusy}"
IsRunning="{Binding IsBusy}"
Color="{StaticResource PrimaryColor}"
VerticalOptions="Center"
HorizontalOptions="Center" />
对<$ c $使用 IsRunning
属性c> IsBusy 属性
Use IsRunning
property with IsBusy
property
private bool _isBusy;
public bool IsBusy
{
get
{
return _isBusy;
}
set
{
_isBusy = value;
RaisePropertyChanged(() => IsBusy);
}
}
在视图模型中
class GalleryViewModel : ExtendedBindableObject
{
...
private async Task DoGetImagesCommand(string pCode, string gCode, string gUrl)
{
IsBusy = true;
var images = await _galleryService.GetImageList(pCode, gCode, gUrl);
foreach (var image in images)
Galleries.Add(image);
IsBusy = false;
}
}
在另一个班级
public abstract class ExtendedBindableObject : BindableObject
{
public void RaisePropertyChanged<T>(Expression<Func<T>> property)
{
var name = GetMemberInfo(property).Name;
OnPropertyChanged(name);
}
private MemberInfo GetMemberInfo(Expression expression)
{
MemberExpression operand;
LambdaExpression lambdaExpression = (LambdaExpression)expression;
if (lambdaExpression.Body is UnaryExpression)
{
UnaryExpression body = (UnaryExpression)lambdaExpression.Body;
operand = (MemberExpression)body.Operand;
}
else
{
operand = (MemberExpression)lambdaExpression.Body;
}
return operand.Member;
}
}
这篇关于Xamarin-将ActivityIndicator可见性绑定到异步任务已完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!