0

我有一个带有 UserControl 作为 ItemTemplate 的 ListView。问题是在过滤和搜索项目之后,项目发生变化并且项目混淆了。例如,尚未下载的项目显示为已下载,已下载的项目显示为未下载。

问题是如何使每个项目单独工作而不影响其他项目?

这是我的列表视图

<ListView ItemsSource="{x:Bind SubtitlesACV, Mode=OneWay}">
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="model:SubsceneDownloadModel">
                        <usercontrol:SubsceneUserControl
                            Title="{x:Bind Title}"
                            Link="{x:Bind Link}"
                            SubtitleLanguage="{x:Bind Language}"
                            Translator="{x:Bind Translator}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

这是我的用户控件

 <Grid>
        <SwipeControl x:Name="ListViewSwipeContainer">
            <Grid VerticalAlignment="Center">
                <Grid.RowDefinitions>
                    <RowDefinition Height="auto"/>
                    <RowDefinition Height="auto"/>
                </Grid.RowDefinitions>
                <TextBlock.../>

                <StackPanel
                    Grid.RowSpan="2"
                    HorizontalAlignment="Right"
                    VerticalAlignment="Center"
                    Orientation="Horizontal">
                    <AppBarButton
                        Name="OpenFolderButton"
                        MinWidth="75"
                        Margin="10,0,10,0"
                        Click="OpenFolderButton_Click"
                        Icon="OpenLocal"
                        IsTabStop="False"
                        Label="Open Folder"
                        Visibility="Collapsed"/>
                    <ProgressRing
                        Name="ProgressStatus"
                        Margin="10,0,10,0"
                        Visibility="Collapsed"/>
                    <AppBarButton
                        Name="DownloadHoverButton"
                        Margin="10,0,10,0"
                        Click="DownloadHoverButton_Click"
                        Icon="Download"
                        IsTabStop="False"
                        Label="Download"
                        Visibility="Collapsed"/>
                </StackPanel>

            </Grid>
        </SwipeControl>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="HoveringStates">
                <VisualState x:Name="HoverButtonsHidden"/>
                <VisualState x:Name="HoverButtonsShown">
                    <VisualState.Setters>
                        <Setter Target="DownloadHoverButton.Visibility" Value="Visible"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>

这是指针事件的代码

private void UserControl_PointerEntered(object sender, PointerRoutedEventArgs e)
        {
            if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse ||
                e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Pen)
            {
                VisualStateManager.GoToState(sender as Control, "HoverButtonsShown", true);
            }
        }

        private void UserControl_PointerExited(object sender, PointerRoutedEventArgs e)
        {
            VisualStateManager.GoToState(sender as Control, "HoverButtonsHidden", true);
        }

此代码用于通过 numberbox 和 AutoSuggestBox 进行过滤(其中 SubtitlesACV 是 AdvancedCollectionView)

SubtitlesACV.Filter = SubtitleFilter;

private bool SubtitleFilter(object subtitle)
        {
            var query = subtitle as SubsceneDownloadModel;
            var selectedLanguage = cmbLanguage.SelectedItem as string;
            var selectedQuality = cmbQuaity.SelectedItem as string;
            if (string.IsNullOrEmpty(selectedQuality) || string.IsNullOrEmpty(selectedLanguage))
                return false;

            var name = query.Name ?? "";
            var translator = query.Translator ?? "";
            var comment = query.Comment ?? "";
            var language = query.Language ?? "";

            if (selectedLanguage.Equals(Consts.ALL_Language))
                selectedLanguage = "";
            
            if (selectedQuality.Equals(Consts.ALL_Qualities))
                selectedQuality = "";

            var episode = $"E{nbEpisode.Value.ToString("00")}";
            if (double.IsNaN(nbEpisode.Value) || nbEpisode.Value == 0)
                episode = "";

            return (name.Contains(selectedQuality, StringComparison.OrdinalIgnoreCase)
                    || translator.Contains(selectedQuality, StringComparison.OrdinalIgnoreCase)
                    || comment.Contains(selectedQuality, StringComparison.OrdinalIgnoreCase))
                    && language.Contains(selectedLanguage, StringComparison.OrdinalIgnoreCase)
                    && (name.Contains(AutoSuggest.Text, StringComparison.OrdinalIgnoreCase)
                    || translator.Contains(AutoSuggest.Text, StringComparison.OrdinalIgnoreCase)
                    || comment.Contains(AutoSuggest.Text, StringComparison.OrdinalIgnoreCase))
                    && (name.Contains(episode, StringComparison.OrdinalIgnoreCase)
                    || translator.Contains(episode, StringComparison.OrdinalIgnoreCase)
                    || comment.Contains(episode, StringComparison.OrdinalIgnoreCase));
        }

首先,下载第 16 集并出现打开文件夹按钮。可以看出,第 17、18 和 19 集显示了下载按钮,这是绝对正确的。

在此处输入图像描述

现在如果我们用以下代码过滤剧集编号,一个尚未下载的项目将显示打开文件夹按钮,这是错误的。

在此处输入图像描述

现在,如果我们从 AutoSuggestBox 搜索第 16 集(之前下载的),所有项目都将变为未下载模式。

在此处输入图像描述

4

1 回答 1

1

首先,您行为的原因是UI 虚拟化。这意味着代表项目的 UI 元素是按需创建的。面板有时会重用一些项目,这就是你得到这种行为的原因。目前,在使用UI virtualization.

如果您没有大量数据,您可以使用StackPanelwhich doesn't enable UI virtualization。但是如果你有大量的数据,那么你需要自己优化性能。例如,将数据切割成不同的部分,一次只加载部分数据。在需要时加载数据的其他部分。这样,您可以避免这种行为。

如果你有大量数据还想使用UI virtualization,你可以做的是清除用户控件中的缓存数据。例如,在加载用户控件或将数据传递到用户控件时,清除该值并手动设置该值。但是你仍然不能完全避免这种行为。

于 2021-08-24T03:24:30.453 回答