UWP 切换开关仅切换视图中的其他项目

UWP toggle switch toggles other items in the view only

我知道这对你来说可能是非常基础的,但请原谅我是 UWP 的新手。

我有使用 Listview 呈现的非常基本的对象列表

                <ListView  Grid.Row="2" Grid.ColumnSpan="2"  BorderBrush="#FF141EE4"  Name="BillsList"
                  SelectionChanged="BillsList_SelectionChanged"
                  FontFamily="Arial" 
                   FlowDirection="LeftToRight" Height="250" >
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <Grid Margin="2">
                                        <Border BorderBrush="Black" BorderThickness="1">
                                            <Grid>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition Height="Auto"/>
                                                    <RowDefinition Height="Auto"/>
                                                    <RowDefinition Height="Auto"/>
                                                    <RowDefinition Height="Auto"/>
                                                    <RowDefinition Height="Auto"/>
                                                    <RowDefinition Height="Auto"/>
                                                </Grid.RowDefinitions>
                                                <TextBlock Margin="5,0,0,0" Grid.Row="0" x:Name="BookTxt" TextWrapping="Wrap" Text="{Binding  bilng_date, Converter={StaticResource billingDateFormatter }}" FontSize="16" Foreground="Black" FontFamily="Arial"/>
                                                <TextBlock Grid.Row="0" Text="الدورة" FontSize="20"  HorizontalAlignment="Right" VerticalAlignment="Center" Foreground="Black" FontFamily="Arial"/>
                                                <TextBlock Margin="5,0,0,0" Grid.Row="1" x:Name="WalkTxt"  TextWrapping="Wrap" Foreground="Black" FontSize="16" Text="{Binding cl_blnce}"  FontFamily="Arial"/>
                                                <TextBlock Grid.Row="1" Text="القيمة" FontSize="20"  HorizontalAlignment="Right" VerticalAlignment="Center" Foreground="Black" FontFamily="Arial"/>
                                                <TextBlock Margin="5,0,0,0" Grid.Row="2" x:Name="paymentTxt"  TextWrapping="Wrap" Foreground="Black" FontSize="16" Text="{Binding payment_no}"  FontFamily="Arial"/>
                                                <TextBlock Grid.Row="2" Text="رقم الفاتورة" FontSize="20"  HorizontalAlignment="Right" VerticalAlignment="Center" Foreground="Black" FontFamily="Arial"/>
                                                <TextBlock Margin="5,0,0,0" Grid.Row="3" x:Name="CollectionState" Text="{Binding delivery_st , Converter={StaticResource AvailabilityToColorConverter}}"  TextWrapping="Wrap" Foreground="Black" FontSize="16"  FontFamily="Arial"/>
                                                <TextBlock Grid.Row="3" Text="حاله الفاتوره" FontSize="20"  HorizontalAlignment="Right" VerticalAlignment="Center" Foreground="Black" FontFamily="Arial"/>
                                                <ToggleSwitch Grid.Row="4" IsOn="False" Toggled="AddToBillsList_Toggled" OffContent="إضافه لقائمه التحصيل" OnContent="حذف من قائمه التحصيل" Visibility="{Binding delivery_st, Converter={StaticResource AvailabilityToCollection}}"  />
                                            </Grid>
                                        </Border>
                                    </Grid>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                            <ListView.ItemContainerStyle>
                                <Style TargetType="ListViewItem">
                                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                                    <!--<Setter Property="Background" Value="LightGreen"/>-->
                                </Style>
                            </ListView.ItemContainerStyle>
                        </ListView>

AddToBillsList_Toggled函数

private void AddToBillsList_Toggled(object sender, RoutedEventArgs e)
    {
        ToggleSwitch toggle = sender as ToggleSwitch;
        if (toggle != null)
        {
            try
            {
                var dataContext = toggle.DataContext;
                var dataItem = (HAND_MH_ST)dataContext;

                if (toggle.IsOn == true)
                {
                    dataItem.isselected = true;
                    statmentCount++;
                    cl_balance += float.Parse(dataItem.cl_blnce);

                    statmentsCount.Text = statmentCount.ToString();
                    statmentsAmount.Text = cl_balance.ToString();
                    Search_statmentsCount.Text = statmentCount.ToString();
                    Search_statmentsAmount.Text = cl_balance.ToString();

                    customersBills.Add(dataItem);
                }

                if (toggle.IsOn == false)
                {
                    dataItem.isselected = false;
                    var idx2 = BillsList.SelectedIndex;
                    statmentCount--;
                    cl_balance -= float.Parse(dataItem.cl_blnce);

                    statmentsCount.Text = statmentCount.ToString();
                    statmentsAmount.Text = cl_balance.ToString();
                    customersBills.Remove(dataItem);
                }


            }
            catch (Exception ex)
            {
                var dialog = new MessageDialog($@"{ex.Message}");
                dialog.ShowAsync().AsTask().Wait();
            }
        }
    }

一切顺利

但是当我使用切换开关时,切换的项目被添加到另一个列表(这是我想要的),但我发现另一个项目被切换(仅在视图中)并且在我滚动时没有添加到其他列表。

所以我对包含所有已切换项目的其他列表执行的任何操作都非常顺利,但发现它有问题

找不到解决此问题的原因

编辑

我在一个全新的应用程序中模拟了如下问题

这是在列表视图中生成 1000 个项目的主页代码

准则

    public class test
{
    public int id { get; set; }
    public string name { get; set; }
}



public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        this.Loaded += CreateData;
    }

    List<test> Holders = new List<test>(); 

    public void CreateData(object sender, RoutedEventArgs e)
    {
        for (int i = 0; i < 1000; i++)
        {
            test obj = new test();
            obj.id = i;
            obj.name = "Toggle";

            Holders.Add(obj);
        }

        ListObjects.ItemsSource = Holders;
    }

    private void ListObjects_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
       
    }
}

}

这是主页的视图

<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="Bisque">
<Grid>
    <ListView Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3" BorderBrush="#FF141EE4" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Name="ListObjects"
                  SelectionChanged="ListObjects_SelectionChanged"  FlowDirection="LeftToRight"
                  FontFamily="Arial" 
                                  Height="250"
                  >
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid Margin="2">
                    <Border Margin="2" BorderBrush="Black" BorderThickness="1" >
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <TextBlock Margin="5,0,0,0" Grid.Row="0" x:Name="SBookTxt" TextWrapping="Wrap" Text="{Binding name}" FontSize="16" Foreground="Black" FontFamily="Arial"/>
                            <ToggleSwitch Grid.Row="1" Name="SaddToBillsList" IsOn="False"  OffContent="Removed" OnContent="Added"   />
                        </Grid>
                    </Border>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                <Setter Property="Background" Value="LightGreen"/>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>
</Grid>

当我 select 例如前 3 个元素时,一切正常

normal selection

但是当我向下滚动时,我发现元素确实被切换了

Toggle Selected without really toggling them

当我滚动回到前 3 个项目时,我 select 在第一个位置编辑,我发现一个元素被删除了

Scroll Back to first 3 elements

此行为是由 UI virtualization 引起的。当您显示大量项目时,它不会同时为 ListView 创建所有项目。有时它会重复使用旧物品。这可以提高性能。

第一种方法是您可以替换 ListView 的默认值 ItemsStackPanel。这将禁用 UI 虚拟化 并且将避免这种行为。但是你会失去一些性能。

        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Vertical" />
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>

第二种方法是您需要将 ToggleSwitch 绑定到 ViewModel 中的布尔值。使用绑定可以降低这种情况发生的可能性,但不能完全禁用这种行为。

<ToggleSwitch Grid.Row="1" Name="SaddToBillsList" IsOn="{Binding IsToggled}"  OffContent="Removed" OnContent="Added" />