2013-02-05 63 views
2

對於這個問題,我做了一個最小的項目,讓每個人都體驗這種行爲。我希望它不只是在我的引擎上運行這樣。列表框和複選框中的大量數據的奇怪行爲[最小項目提供]

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

而且我smple數據類:

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

然後,當您檢查列表頂部或底部的項目時,就會出現問題。

+2

爲什麼你處理複選框檢查事件youself - 你不能使用雙向綁定?請參閱http://stackoverflow.com/questions/8642660/checkbox-two-way-binding-doesnt-work – Jay

+0

我現在試過,但問題仍然存在。 –

+0

我編輯了我的問題。我最小的例子中的列表似乎太短了。僅當您檢查最底部的項目並在此之後滾動時纔會出現問題。或者你可以用更多的對象擴展列表。 –

回答

2

永不保存複選框的選中狀態。修復您的XAML:

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

+0

謝謝,就是這樣。 –