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

发布于 2025-01-15 17:39:13 字数 9382 浏览 0 评论 0原文

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

渲染的非常基本的对象列表,

                <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>

我有使用 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)
    {
       
    }
}

}

这是当我选择前 3 个元素时主页的视图

<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>

,例如一切正常

正常选择

但是当我向下滚动时,我发现元素被切换,并真正切换了它们

切换所选内容而不真正切换它们

,当我滚动回我在第一个位置选择的前 3 个项目时,我发现一个元素已被删除

滚动回到前 3 个元素

I know this is maybe very basic to you, but excuse me as am new in UWP .

i has very basic List of objects rendered using 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>

the AddToBillsList_Toggled function

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();
            }
        }
    }

every things goes very well

but when I use toggle switch the item toggled is added to another list( which what I want ), but i find another items got toggled ( in view only) and not add to other list when I scroll .

so any action i took on other list that containes all toggled items goes very well, but view something wrong with it

cant find why such a behavior happened to fix it

Edit

I simulated the problem as follow in a completely new app

this is the mainpage code which generate 1000 items in the listview

the Code

    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)
    {
       
    }
}

}

here is the view of the main page

<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>

when i select the first 3 elements for example every thing is ok

normal selection

but when i scroll down i found elements got toggled with really toggling them

Toggle Selected without really toggling them

and when i scroll back to the first 3 items i selected at first place i found one element removed

Scroll Back to first 3 elements

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

愁杀 2025-01-22 17:39:13

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

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

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

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

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

This behavior is caused by the UI virtualization. It will not create all the items at the same time for the ListView when you are showing large amount of items. And sometimes it will reuse the old items. This could improve the performance.

The first way to this is that you could replace the default ItemsStackPanel of the ListView. This will disable the UI virtualization and this behavior will be avoided. But you will lose some performance.

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

The second way is that you need to bind the ToggleSwitch to a bool value inside the ViewModel. Using binding could reduce the probability of this happening but it can't completely disable this behavior.

<ToggleSwitch Grid.Row="1" Name="SaddToBillsList" IsOn="{Binding IsToggled}"  OffContent="Removed" OnContent="Added" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文