gpt4 book ai didi

c# - 当我将其 ItemsPanel 覆盖为包装面板时,为什么列表框需要永远加载?

转载 作者:行者123 更新时间:2023-11-30 22:09:32 26 4
gpt4 key购买 nike

我正在尝试将项目(图像)添加到列表框,最好使用 WrapPanel 类型布局。很简单。

我遇到的问题是,当我定义 ListBox.ItemsPanel 模板以使用包装面板时,加载图像所花费的时间变得难以忍受。我目前正在添加大约 70 张图像,但我希望它能支持数千张图像。

如果我不自定义列表框,加载速度会非常快。我在下面的 XAML 中提到了我正在更改的部分。

我不明白的是

  1. 为什么这样一个看似很小的 xaml 更改会使应用程序卡住
  2. 我如何仍能获得具有良好性能的 wrapppanel 类型布局。

    <Grid>
    <Grid.RowDefinitions>
    <RowDefinition></RowDefinition>
    <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>

    <Button Grid.Row=0 Name="ImageButton" Click="ImageButton_Click">GET IMAGES</Button>

    <ListBox Grid.Row="1" Name="ImageCollection" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
    <!-- Items added to list panel using Wrap Panel Template. -->
    <!-- By removing the below, things go pretty fast -->
    <!-- When the ListBox.ItemsPanel uses a wrappanel as below, loading up the images is SLOW. If I delete the below, loading is FAST, but isn't what I want. -->

    <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
    <WrapPanel/>
    </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    </ListBox>
    </Grid>

我的代码背后看起来像这样。我在这里没有更改任何内容,只是将其作为信息包含在内。

    public AsyncGet()
{
InitializeComponent();
}

private List<String> images = new List<string>(
Directory.GetFiles(@"C:\Users\me\Pictures\wallpapers")
);

private void ImageButton_Click(object sender, RoutedEventArgs e)
{
foreach (string s in images)
{
Image image = new Image();
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(s);
bi.EndInit();
image.Source = bi;
image.Height = 200;
image.Width = 200;
ImageCollection.Items.Add(image);
}
}

编辑

在尝试了一些我不太满意的 VirtualWrapPanel 实现之后,我决定坚持使用 WrapPanel。我做了一些似乎可以保持主线程响应的事情:

  1. 将 BitMapImage 解码尺寸和图像尺寸保持在 200
  2. 通过为每个项目添加默认图像来开始加载。预期路径存储在图像标签中。
  3. 遍历每个项目更新源,使用 async/await 生成 bitmapImage。

我不知道我是否按照预期的方式使用 async/await。但它似乎允许 UI 保持响应。图像循环并最终替换所有默认值,这可能比其他方式花费更长的时间,但我更喜欢仍然接受用户输入的能力。

我希望我能找到一种方法对此进行数据绑定(bind),稍后我可能会尝试。

private List<String> images = new List<string>(
Directory.GetFiles(@"C:\Users\me\Pictures\wallpapers")
);

private Image defaultImage;

public AsyncGet()
{
InitializeComponent();
DataContext = this;
defaultImage = new Image();
defaultImage.Source = MakeBitmapImage( @"C:\Users\me\Pictures\MeowShawn_Lynch.jpg");
defaultImage.Height = 200;
defaultImage.Width = 200;
}

private async void ImageButton_Click(object sender, RoutedEventArgs e)
{
ImageCollection.Items.Clear();

foreach(string s in images)
{
Image image = new Image();
image.Source = defaultImage.Source;
image.Height = defaultImage.Height;
image.Width = defaultImage.Width;
ImageCollection.Items.Add(image);
image.Tag = s;
}

foreach (Image image in ImageCollection.Items)
{
string path = image.Tag.ToString();
Task<BitmapImage> task = new Task<BitmapImage>(() => MakeBitmapImage(path, true));
task.Start();

image.Source = await task;
}
}

private BitmapImage MakeBitmapImage(string path, Boolean freeze = false)
{
BitmapImage bi = new BitmapImage();

bi.CacheOption = BitmapCacheOption.OnLoad;
bi.BeginInit();
bi.UriSource = new Uri(path);
bi.DecodePixelHeight = 200;

bi.EndInit();
if (freeze)
{
bi.Freeze();
}
return bi;
}

最佳答案

默认 ListBox 将使用 VirtualizingStackPanel它不会渲染当前不在 View 中的元素。

The word "virtualize" refers to a technique by which a subset of user interface (UI) elements are generated from a larger number of data items based on which items are visible on-screen. Generating many UI elements when only a few elements might be on the screen can adversely affect the performance of your application. The VirtualizingStackPanel calculates the number of visible items and works with the ItemContainerGenerator from an ItemsControl (such as ListBox or ListView) to create UI elements only for visible items.

WrapPanel 没有该功能,所有项目都被视为可见。你可以尝试使用这个 Virtualizing WrapPanel控制。

对于普通的ListBox,使用默认的ItemsPanel,你可以通过设置VirtualizingStackPanel.IsVirtualizing来控制虚拟化。附加属性:

<ListBox VirtualizingStackPanel.IsVirtualizing="True" 

关于c# - 当我将其 ItemsPanel 覆盖为包装面板时,为什么列表框需要永远加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21515820/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com