我有一个针对Windows桌面的C#应用程序。该应用程序显示图像列表。当用户单击列表视图中的任何图像时,应用程序会放大(详细视图)它&显示图像(随着图像大小的增大,会显示出某种全屏)。
每当我单击列表视图中的任何图像时,详细视图中的图像首先显示以前加载的图像&然后刷新和加载当前选择的图像
我想知道如何防止加载之前的图像,直到,新的图像是取回?
当前,每当用户单击列表视图中的项时,我首先用空白图像加载详细视图图像源,然后获取所需的图像并加载它。
我的密码在这里:
await CallOnUiThreadAsync(() =>
{
/*Load empty image first*/
imgBitmap = new BitmapImage();
var uri = new System.Uri("ms-appx:///Assets/emptyImage.png");
imgBitmap.UriSource = uri;
img.Source = imgBitmap;
});
if (("/Assets/emptyImage.png" != url) || (url != String.Empty))
{
await Task.Run(async () =>
{
/*image_fetch is our proprietary api. It returns a byte array*/
byte[] imageBytes = image_fetch;
MemoryStream stream = new MemoryStream(imageBytes, 0, imageBytes.Length, true);
var randomAccessStream = new MemoryRandomAccessStream(stream);
await CallOnUiThreadAsync(async () =>
{
imgBitmap = new BitmapImage();
await imgBitmap.SetSourceAsync(randomAccessStream);
img.Source = imgBitmap;
});
});
}
我已经在后台线程中运行image_fetch,但从用户单击列表视图项到图像加载细节视图为止,我仍然看到了一个小的滞后。
我想减少延迟。除了加载空白图像之外,还有其他更好的方法吗?
发布于 2016-05-30 08:04:20
每当我单击列表视图中的任何图像时,详细视图中的图像首先显示以前加载的图像,然后刷新和加载当前选择的图像。
我认为问题在于您的Mater/Detail结构是如何实现的。从您的代码中我可以看到,您可能从文件中读取图像并将BitmapImage
设置为ListView
中的Image
源,这里我创建了一个示例,当窗口的宽度超过720时,详细信息将显示在Master的右侧,如果宽度小于720,细节将被放大(全屏)。
我的MainPage:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="AdaptiveStates">
<VisualState x:Name="DefaultState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="720" />
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="NarrowState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="MasterColumn.Width" Value="*" />
<Setter Target="DetailColumn.Width" Value="0" />
<Setter Target="MasterListView.SelectionMode" Value="None" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="MasterColumn" Width="320" />
<ColumnDefinition x:Name="DetailColumn" Width="*" />
</Grid.ColumnDefinitions>
<ListView x:Name="MasterListView" Grid.Column="0" ItemContainerTransitions="{x:Null}"
IsItemClickEnabled="True" ItemClick="MasterListView_ItemClick" ItemsSource="{x:Bind itemcollection}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:TestItem">
<Image Source="{x:Bind ImageItem}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ContentPresenter x:Name="DetailContentPresenter" Grid.Column="1" BorderThickness="1,0,0,0"
Padding="24,0" BorderBrush="{ThemeResource SystemControlForegroundBaseLowBrush}"
Content="{x:Bind MasterListView.SelectedItem, Mode=OneWay}">
<ContentPresenter.ContentTemplate>
<DataTemplate x:DataType="local:TestItem">
<Image Source="{x:Bind ImageItem}" />
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Grid>
代码背后:
private ObservableCollection<TestItem> itemcollection = new ObservableCollection<TestItem>();
public MainPage()
{
this.InitializeComponent();
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
StorageFolder picLib = KnownFolders.PicturesLibrary;
var picfiles = await picLib.GetFilesAsync();
foreach (var pic in picfiles)
{
BitmapImage bmp = new BitmapImage();
IRandomAccessStream stream = await pic.OpenReadAsync();
bmp.SetSource(stream);
itemcollection.Add(new TestItem { ImageItem = bmp });
}
}
private void MasterListView_ItemClick(object sender, ItemClickEventArgs e)
{
var clickedItem = (TestItem)e.ClickedItem;
if (AdaptiveStates.CurrentState == NarrowState)
{
Frame.Navigate(typeof(DetailPage), clickedItem);
}
}
我的详细资料页:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Image Source="{x:Bind image}" />
</Grid>
代码背后:
private BitmapImage image;
public DetailPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var testitem = e.Parameter as TestItem;
image = testitem.ImageItem;
var backStack = Frame.BackStack;
var backStackCount = backStack.Count;
if (backStackCount > 0)
{
var masterPageEntry = backStack[backStackCount - 1];
backStack.RemoveAt(backStackCount - 1);
// Doctor the navigation parameter for the master page so it
// will show the correct item in the side-by-side view.
var modifiedEntry = new PageStackEntry(
masterPageEntry.SourcePageType,
e.Parameter,
masterPageEntry.NavigationTransitionInfo
);
backStack.Add(modifiedEntry);
}
// Register for hardware and software back request from the system
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested += DetailPage_BackRequested;
systemNavigationManager.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested -= DetailPage_BackRequested;
systemNavigationManager.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
}
private void OnBackRequested()
{
Frame.GoBack();
}
private void DetailPage_BackRequested(object sender, BackRequestedEventArgs e)
{
e.Handled = true;
OnBackRequested();
}
我的TestItem
类在这里非常简单:
public class TestItem
{
public BitmapImage ImageItem { get; set; }
}
您也可以参考官方的主/详细样本。我根据这个官方的例子写了我的样本,这里的要点是:
我已经在后台线程中运行image_fetch,但从用户单击列表视图项到图像加载细节视图为止,我仍然看到了一个小的滞后。
您是否每次单击ListViewItem时都会获取图像源(例如从文件中获取),那么您能将图像源设置为详细帧吗?在这里,使用DataBinding,当您想要向ListView
添加数据时,您可以只获取所有的图像。
发布于 2017-01-02 22:51:42
您可以使用FFImageLoading,它使用各种方法优化图像加载(包括下载/内存缓存):
XML <ff:FFImage VerticalAlignment="Stretch" HorizontalAlignment="Stretch" TransformPlaceholders="False" LoadingPlaceholder="loading.png" ErrorPlaceholder="error.png" Height="500" Width="500" Source="http://loremflickr.com/600/600/nature?filename=simple.jpg">
https://stackoverflow.com/questions/37475023
复制相似问题