Xaml 异步显示来自internet的图像
在我的UWP应用程序中,我有一个带有增量加载的Xaml 异步显示来自internet的图像,xaml,uwp,Xaml,Uwp,在我的UWP应用程序中,我有一个带有增量加载的列表视图。现在,我还需要在列表视图项中包含一个图像。我试着直接给它URI 其中ThumbnailImage在我的视图模型中只是一个字符串。问题是,由于增量加载,当我向下滚动一点,而之前的图像仍在加载时,应用程序只是挂起。然而,如果我让所有的图像显示,然后向下滚动,它的工作很好 我还尝试了工具箱中的ImageEx控件,它也有同样的问题 我做了一些搜索,唯一找到的是在XAML中执行IsAsync=True。但似乎IsAsync在UWP中不可用 我的Vie
列表视图。现在,我还需要在列表视图项中包含一个图像。我试着直接给它URI
其中ThumbnailImage
在我的视图模型中只是一个字符串。问题是,由于增量加载,当我向下滚动一点,而之前的图像仍在加载时,应用程序只是挂起。然而,如果我让所有的图像显示,然后向下滚动,它的工作很好
我还尝试了工具箱中的ImageEx
控件,它也有同样的问题
我做了一些搜索,唯一找到的是在XAML中执行IsAsync=True
。但似乎IsAsync
在UWP中不可用
我的ViewModel:
public class MyViewModel
{
...
public string ThumbnailImage { get; set; }
...
}
我的XAMLListView
以增量方式填充
<ListView Grid.Row="0"
SelectionMode="Single"
IsItemClickEnabled="True"
ItemClick="SearchResultListView_ItemClick" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="BorderBrush" Value="Gray"/>
<Setter Property="BorderThickness" Value="0, 0, 0, 1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter
ContentTransitions="{TemplateBinding ContentTransitions}"
SelectionCheckMarkVisualEnabled="True"
CheckBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
CheckBoxBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
DragBackground="{ThemeResource ListViewItemDragBackgroundThemeBrush}"
DragForeground="{ThemeResource ListViewItemDragForegroundThemeBrush}"
FocusBorderBrush="{ThemeResource SystemControlForegroundAltHighBrush}"
FocusSecondaryBorderBrush="{ThemeResource SystemControlForegroundBaseHighBrush}"
PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}"
PointerOverBackground="{ThemeResource SystemControlDisabledTransparentBrush}"
SelectedBackground="{ThemeResource SystemControlDisabledTransparentBrush}"
SelectedForeground="{ThemeResource SystemControlDisabledTransparentBrush}"
SelectedPointerOverBackground="{ThemeResource SystemControlDisabledTransparentBrush}"
PressedBackground="{ThemeResource SystemControlDisabledTransparentBrush}"
SelectedPressedBackground="{ThemeResource SystemControlDisabledTransparentBrush}"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
ContentMargin="{TemplateBinding Padding}"
CheckMode="Inline"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="viewModel:MyViewModel">
<UserControl >
<Grid Style="{StaticResource SomeStyle}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="VisualStatePhone">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ThumbnailImage.Width" Value="50"/>
<Setter Target="ThumbnailImage.Height" Value="50"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="VisualStateTablet">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="600" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ThumbnailImage.Width" Value="70"/>
<Setter Target="ThumbnailImage.Height" Value="70"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="VisualStateDesktop">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1200" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ThumbnailImage.Width" Value="90"/>
<Setter Target="ThumbnailImage.Height" Value="90"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition MaxHeight="30"></RowDefinition>
<RowDefinition MaxHeight="30"></RowDefinition>
<RowDefinition MaxHeight="30"></RowDefinition>
<RowDefinition MaxHeight="30"></RowDefinition>
<RowDefinition MaxHeight="30"></RowDefinition>
<RowDefinition MaxHeight="10"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="{x:Bind ThumbnailImage}"
Visibility="{x:Bind ThumbnailImage, Converter={StaticResource BoolToVisibilityImage}}"
Name="ThumbnailImage"/>
<TextBlock Text="{x:Bind Name}" .../>
<Grid Grid.Row="1"
Grid.Column="1"
Visibility="{x:Bind Source, Converter={StaticResource ConverterNameHere}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Bind lblSource, Mode=OneWay}" .../>
<TextBlock Text="{x:Bind Source}" .../>
</Grid>
<Grid Grid.Row="2"
Grid.Column="1"
Visibility="{x:Bind Author, Converter={StaticResource ConverterNameHere}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Bind lblAuthor, Mode=OneWay}" .../>
<TextBlock Text="{x:Bind Author}" .../>
</Grid>
<TextBlock Text="{x:Bind EducationalLevel}" .../>
<StackPanel Orientation="Horizontal"
Grid.Row="4"
Grid.Column="1">
<ItemsControl ItemsSource="{x:Bind AccessRights}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{x:Bind Languages}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<ItemsControl ItemsSource="{x:Bind TypeImages}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</UserControl>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
这是我的增量加载类:
public class ItemsToShow : ObservableCollection<MyViewModel>, ISupportIncrementalLoading
{
private SearchResponse ResponseObject { get; set; } = new SearchResponse();
MyViewModel viewModel = null;
public bool HasMoreItems
{
get
{
if ((string.IsNullOrEmpty(SearchResultDataStore.NextPageToken) && !SearchResultDataStore.IsFirstRequest) || SearchResultDataStore.StopIncrementalLoading)
return false;
if(SearchResultDataStore.IsFirstRequest)
{
using (var db = new DbContext())
{
var json = db.UpdateResponse.First(r => r.LanguageId == DataStore.Language).JsonResponse;
Metadata = Newtonsoft.Json.JsonConvert.DeserializeObject<UpdateApiResponse>(json).response.metadata.reply;
}
var returnObject = SearchResultDataStore.SearchResponse;
ResponseObject = returnObject.response;
//This will show a grid with some message for 3 seconds on a xaml page named SearchResultPage.
Toast.ShowToast(ResponseObject.message, SearchResultPage.Current.ToastGrid);
}
else
{
SearchApiResponse returnObject = null;
try
{
returnObject = new SearchApiCall().CallSearchApiAsync(param1, param2, param3).Result;
}
catch
{
return false;
}
ResponseObject = returnObject.response;
}
try
{
return ResponseObject.documents.Count > 0;
}
catch { return false; }
}
}
public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
{
CoreDispatcher coreDispatcher = Window.Current.Dispatcher;
return Task.Run<LoadMoreItemsResult>(async () =>
{
await coreDispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
foreach (var item in ResponseObject.documents)
{
this.Add(PrepareViewModel(item));
}
});
await Task.Delay(350);
return new LoadMoreItemsResult() { Count = count };
}).AsAsyncOperation<LoadMoreItemsResult>();
}
public MyViewModel PrepareViewModel(Document document)
{
viewModel = new MyViewModel();
viewModel.property1 = document.value1;
viewModel.property2 = document.value2;
...
...
if(SearchResultDataStore.ShowImage)
{
//thumbnailUrl is a string.
viewModel.ThumbnailImage = document.thumbnailUrl;
}
else
{
viewModel.ThumbnailImage = "somegarbage.png";
}
...
...
return viewModel;
}
}
公共类项显示:ObservableCollection,ISupportIncrementalLoading
{
private SearchResponse ResponseObject{get;set;}=new SearchResponse();
MyViewModel viewModel=null;
公共物品
{
得到
{
if((string.IsNullOrEmpty(SearchResultDataStore.NextPageToken)和&!SearchResultDataStore.IsFirstRequest)| | SearchResultDataStore.StopIncrementalLoading)
返回false;
if(SearchResultDataStore.IsFirstRequest)
{
使用(var db=new DbContext())
{
var json=db.UpdateResponse.First(r=>r.LanguageId==DataStore.Language).JsonResponse;
Metadata=Newtonsoft.Json.JsonConvert.DeserializeObject(Json).response.Metadata.reply;
}
var returnObject=SearchResultDataStore.SearchResponse;
ResponseObject=returnObject.response;
//这将在一个名为SearchResultPage的xaml页面上显示一个包含一些消息的网格,持续3秒钟。
Toast.ShowToast(ResponseObject.message,SearchResultPage.Current.ToastGrid);
}
其他的
{
SearchApiResponse returnObject=null;
尝试
{
returnObject=new SearchApiCall().CallSearchApiAsync(param1,param2,param3).Result;
}
抓住
{
返回false;
}
ResponseObject=returnObject.response;
}
尝试
{
返回响应object.documents.Count>0;
}
catch{return false;}
}
}
公共IAsyncOperation LoadMoreItemsAsync(uint计数)
{
corespatcher corespatcher=Window.Current.Dispatcher;