gpt4 book ai didi

wpf - 当返回页面导航时,Listview 将检查应用于其他具有复选框的 listview 项目

转载 作者:行者123 更新时间:2023-12-04 21:49:17 26 4
gpt4 key购买 nike

我有一个 ListViewCheckBox 控件,当页面包含ListView 已返回导航。

具体来说,我对包含大约 300 个项目的 ListView 中的一些项目应用了复选标记。然后我点击一个调用另一个应用程序启动的 Button,然后当我使用 ListView 返回到我的原始应用程序并向下滚动 ListView,我观察到一种神秘选中的复选框模式,这些复选框遵循我在 ListView 中创建的原始选中位置的模式。

注意:我在 ListView 中使用虚拟化。只有当导航返回到包含 ListView 的页面时,才会出现神秘的选中复选框。

复选框不应该被神秘地选中。XAML:

<ListView   x:Name="ContactList" 
ItemsSource="{Binding SelectedCategory.Contacts}"
SelectedItem="{Binding SelectedContact, Mode=TwoWay}"
ScrollViewer.VerticalScrollMode="Enabled"
Height="600"
Width="425"
Margin="58,175,0,0" Canvas.ZIndex="99"
Background="Transparent" Foreground="#FF333747"
VerticalAlignment="Top" HorizontalAlignment="Left">

<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox x:Name="checkbox" Style="{StaticResource CheckBoxStyle1}"
Visibility="{Binding ElementName=grid, Path=DataContext.BroadcastActivated, Converter={StaticResource BoolToVisibilityConverter}, Mode=TwoWay}"
Margin="0,-8" BorderBrush="#FF4E58BC" Checked="ContactChecked" Unchecked="ContactUnchecked">
</CheckBox>

<TextBlock Text="{Binding DisplayName}" Width="425">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Holding">
<behaviors:MoveContactAction />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>

<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Family" Command="{Binding ElementName=grid, Path=DataContext.MoveCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
<MenuFlyoutItem Text="Friend" Command="{Binding ElementName=grid, Path=DataContext.MoveCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
<MenuFlyoutItem Text="Business" Command="{Binding ElementName=grid, Path=DataContext.MoveCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
<MenuFlyoutItem Text="Met" Command="{Binding ElementName=grid, Path=DataContext.MoveCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
<MenuFlyoutItem Text="Others" Command="{Binding ElementName=grid, Path=DataContext.MoveCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
</TextBlock>
</StackPanel>
</DataTemplate>

</ListView.ItemTemplate>

<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>

<ListView.Template>
<ControlTemplate TargetType="ListView">
<Border>
<ScrollViewer>
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
</ListView.Template>

<Interactivity:Interaction.Behaviors>
<behaviors:ContactSelectionBehavior />
<Core:DataTriggerBehavior Binding="{Binding DataContext.BusinessRequested, ElementName=grid}" Value="True">
<Core:GoToStateAction StateName="BusinessSelectedState"/>
</Core:DataTriggerBehavior>
<Core:DataTriggerBehavior Binding="{Binding DataContext.FriendsRequested, ElementName=grid}" Value="True">
<Core:GoToStateAction StateName="FriendsSelectedState"/>
</Core:DataTriggerBehavior>
<Core:DataTriggerBehavior Binding="{Binding DataContext.FamilyRequested, ElementName=grid}" Value="True">
<Core:GoToStateAction StateName="FamilySelectedState"/>
</Core:DataTriggerBehavior>
<Core:DataTriggerBehavior Binding="{Binding DataContext.OthersRequested, ElementName=grid}" Value="True">
<Core:GoToStateAction StateName="OthersSelectedState"/>
</Core:DataTriggerBehavior>
<Core:DataTriggerBehavior Binding="{Binding DataContext.AllRequested, ElementName=grid}" Value="True">
<Core:GoToStateAction StateName="AllSelectedState"/>
</Core:DataTriggerBehavior>
<Core:DataTriggerBehavior Binding="{Binding DataContext.MetRequested, ElementName=grid}" Value="True">
<Core:GoToStateAction StateName="MetSelectedState"/>
</Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>

<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="FontSize" Value="26" />
<Setter Property="Margin" Value="0,10" />
<Setter Property="Foreground" Value="#FF333747" />
</Style>
</ListView.ItemContainerStyle>
</ListView>

代码隐藏:

private void ContactChecked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
var control = sender as CheckBox;
var viewModel = this.DataContext as HomeViewModel;

var contact = control.DataContext as Contact;
viewModel.SelectedContacts.Add(contact);

if (CallButton.IsEnabled)
{
CallButton.IsEnabled = false;
}

SetMessageContactOptionsEnabledState(viewModel);
}

private void ContactUnchecked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
var control = sender as CheckBox;
var viewModel = this.DataContext as HomeViewModel;

var contact = control.DataContext as Contact;
viewModel.SelectedContacts.Remove(contact);
}

更新:无需导航至其他应用即可重现此问题。

最佳答案

我设法在新的 Windows Phone 8.1 项目中重现了您的问题(同样适用于 WPF 等):

MainPage.xaml

<Page
x:Class="App27.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App27"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Loaded="Page_Loaded">

<Grid>
<ListView x:Name="listview">
<ListView.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>

MainPage.xaml.cs

class Model
{
public string Name { get; set; }
}

public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}

private void Page_Loaded(object sender, RoutedEventArgs e)
{
var items = new List<Model>();
for (var i = 0; i < 100; i++)
items.Add(new Model { Name = i.ToString() });
listview.ItemsSource = items;
}
}

这是一个极其基本的示例,它创建了一个页面,该页面具有包含每个项目的复选框的 ListView 。如果我选中前三项并向下滚动,则会选中一些后续复选框,如下图所示:

screenshot

我的猜测是,由于启用了虚拟化(默认情况下), ListView 会在您向下滚动时重新使用现有的 ListViewItem,其中一些包含我之前检查过的复选框元素。重复使用容器时不会清除此复选框的状态。

假设我的 ListView 中有 100 个项目,由于虚拟化,内存中只会创建 20 个 ListViewItem。那么,如果内存中只有 20 个复选框,应用程序应该如何记住 100 个项目中的哪些应该有一个选中的复选框?

您应该将每个项目的选中状态存储在您的 View 模型中并对其进行数据绑定(bind)。当 ListView 需要重用 ListView 项目时,它会将其数据上下文设置为新项目,从而导致复选框由于其具有的绑定(bind)而更新其状态。

您应该对您的复选框进行此更改:

<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked, Mode=TwoWay}" />

并将 IsChecked 属性添加到项目的模型中:

class Model
{
public string Name { get; set; }
public bool IsChecked { get; set; }
}

注意:只有当您启用了虚拟化时才需要这样做。如果您的列表不会包含太多项目,那么您可以通过使用非虚拟化面板(例如 StackPanel)来禁用虚拟化:

<ListView x:Name="listview">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
...
</ListView>

当然,这些示例是基于我的简化示例,但仍然适用于您的代码。

看起来每个复选框都附加了一些特定的行为,否则我建议只在 ListView 上设置 SelectionMode="Multiple" 以立即使用复选框。

关于wpf - 当返回页面导航时,Listview 将检查应用于其他具有复选框的 listview 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25510762/

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