c# - ListBox 和 Checkbox 中存在大量数据的奇怪行为 [提供的最小项目]

标签 c# silverlight windows-phone-7 listbox

对于这个问题,我做了一个最小的项目,让每个人都体验这种行为。我希望这不仅仅是我的发动机这样运转。

minimal project

在我的项目中,我实现了一个包含大量示例数据的列表框。列表框还为每个项目都有一个复选框元素。

问题:首先,我选中/取消选中列表框中的复选框。然后我在列表框中滚动几次。现在我注意到很多复选框被随机选中/取消选中。如果我将 ListBox 缩小一点(请参阅源代码中的注释),则不会出现奇怪的行为。编辑::如果您没有此问题,请尝试检查列表最底部的项目。也许您必须用更多对象来扩展列表才能看到问题。

这里是一些代码片段。如您所见,我已经尝试使用 List/ObservableCollection、PropertyChanged 和 LongListSelector 而不是 Listbox。

C#

    // Already tried to use simple List<SampleCheckedData> buildings. 
    // Doesnt change anything.
    private ObservableCollection<SampleCheckedData> buildings;

    // Already tried with this as well.
    /*protected ObservableCollection<SampleCheckedData> Buildings
    {
        get
        {
            return buildings;
        }
        set
        {
            buildings = value;
        }
    }*/

    public MainPage()
    {
        InitializeComponent();

        buildings = new ObservableCollection<SampleCheckedData>();

        buildings.Add(new SampleCheckedData() { Name = "Cloudy", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Sun", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Drizzle", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Snow", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Cloudy", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Sun", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Drizzle", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Snow", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Cloudy", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Sun", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Cloudy", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Sun", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Drizzle", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Snow", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Cloudy", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Sun", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Cloudy", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Sun", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Drizzle", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Snow", IsChecked = false });

        // If you comment this data out, the listbox is smaller and no problem occurs in my case.
        buildings.Add(new SampleCheckedData() { Name = "Cloudy" , IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Sun", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Cloudy", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Sun", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Drizzle", IsChecked = false });
        buildings.Add(new SampleCheckedData() { Name = "Snow", IsChecked = false });
        // If you comment this data out, the listbox is smaller and no problem occurs in my case. [END]

        this.listBox2.ItemsSource = buildings;
    }

我的选中/取消选中事件:

    private void CheckBox_Checked(object sender, RoutedEventArgs e)
    {
        //Use this if you use the LongListSelector.
        //ListBoxItem checedItem = this.listBox2.SelectedItem as ListBoxItem;

        ListBoxItem checedItem = this.listBox2.ItemContainerGenerator.ContainerFromItem((sender as CheckBox).DataContext) as ListBoxItem;
        if (checedItem != null)
        {
            checedItem.IsSelected = true;
        }
    }

    private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
    {
        //Use this if you use the LongListSelector.
        //ListBoxItem checedItem = this.listBox2.SelectedItem as ListBoxItem;

        ListBoxItem checedItem = this.listBox2.ItemContainerGenerator.ContainerFromItem((sender as CheckBox).DataContext) as ListBoxItem;
        if (checedItem != null)
        {
            checedItem.IsSelected = false;
        }
    }

还有我的简单数据类:

public class SampleCheckedData
{
    //Already tried with this, but it is not working.

    /*
    private bool _isChecked;
    public bool IsChecked
    {
        get { return _isChecked; }
        set
        {
            if (_isChecked != value)
            {
                _isChecked = value;
                NotifyPropertyChanged("IsChecked");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    } 
    */

    public bool IsChecked
    {
        get;
        set;
    }

    public string Name
    {
        get;
        set;
    }
}

XAML

我的内容如下所示:

    <!--ContentPanel - zusätzliche Inhalte hier platzieren-->
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

        <ListBox x:Name="listBox2" SelectionMode="Multiple">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox IsChecked="{Binding IsChecked}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>
                        <TextBlock Text="{Binding Name}" Width="150" VerticalAlignment="Center"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <!--//Use this if you use the LongListSelector.-->
        <!--<toolkit:LongListSelector  x:Name="listBox2"  Background="Transparent" IsFlatList="True"   ItemTemplate="{StaticResource citiesItemTemplate}" />-->

    </Grid>

如果您想尝试使用 LongListSelector,可选包括:

    <DataTemplate x:Key="citiesItemTemplate">
        <StackPanel Grid.Column="1"  VerticalAlignment="Top">
            <TextBlock Text="{Binding Name}" FontSize="26"  Margin="12,-12,12,6"/>
            <CheckBox IsChecked="{Binding IsChecked}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>
        </StackPanel>
    </DataTemplate>

xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls; assembly=Microsoft.Phone.Controls.Toolkit"

希望有人能解决这个问题。没有找到任何线索...

编辑:

相关问题:

One Two Three

编辑:

我注意到您必须在列表中添加更多 eobjects 才会出现此问题:

    buildings.Add(new SampleCheckedData() { Name = "Cloudy", IsChecked = false });
    buildings.Add(new SampleCheckedData() { Name = "Sun", IsChecked = false });
    buildings.Add(new SampleCheckedData() { Name = "Cloudy", IsChecked = false });
    .....

然后,当您检查列表最顶部或最底部的项目时,就会出现问题。

最佳答案

您永远不会保存复选框的选定状态。修复您的 XAML:

<CheckBox IsChecked="{Binding IsChecked,Mode=TwoWay}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>

关于c# - ListBox 和 Checkbox 中存在大量数据的奇怪行为 [提供的最小项目],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14703379/

相关文章:

c# - 如何用C#实现视频直播?

c# - 将两个形状连接在一起,Silverlight 2

silverlight - MVVM Light、Windows Phone、View & ViewModel 在页面之间导航

c# - 在具有返回对象 T 的方法中 try catch

c# - 什么时候配置 Log4Net?

c# - 即时更改 UI 语言

c# - 是否可以在不使用任何实际电子邮件帐户的情况下以编程方式发送电子邮件

xaml - 应用程序栏 Windows Phone

c# - 使用反射调用 Enumerable.Where(或其他重载的泛型方法)

C# bool 和 bool ? jQuery 验证问题