none
WPF ListBox SelectedItems问题 RRS feed

  • 问题

  •  
     <Style x:Key="CheckBoxListStyle" TargetType="{x:Type ListBox}">
                <Setter Property="SelectionMode" Value="Multiple"></Setter>
                <Setter Property="ItemContainerStyle">
                    <Setter.Value>
                        <Style TargetType="{x:Type ListBoxItem}">
                            <Setter Property="Margin" Value="2"></Setter>
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                        <CheckBox Focusable="False"
                                                  IsChecked="{Binding Path=IsSelected,Mode=TwoWay,
                                            RelativeSource={RelativeSource TemplatedParent}}">
                                            <ContentPresenter></ContentPresenter>
                                        </CheckBox>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </Setter.Value>
                </Setter>
            </Style>

    使用上面的样式,让ListBox变成了带复选框项的ListBox

    在代码中获取数据集赋值给ListBox显示列表项

    lstShow.ItemsSource=GetDataDB();

    这样界面上显示了查询的数据项,选择其中某些项后,点击Button通过lstShow.SelectedItems获取选中的项,

    然后,lstShow.ItemsSource=null;清除掉ListBox显示的内容,但是此时如果再次点击Button,仍然可以通过lstShow.SelectedItems获取到上次选中的项,这里让我很郁闷,lstShow.ItemsSource=null;ListBox都没有任何显示的选项了为什么获取SelectedItems还有值呢?我怀疑是我上面的模板有问题,请各位高手帮忙改正改正

    2013年1月23日 7:34

答案

  • 你好,

    在看过了你的style代码后,我认为这个问题不是出在style部分,估计是你在别的地方对selected Item进行了设置。

    建议你在清除ItemsSource 或某个items之后对ListBoxitems进行刷新:

      lstShow.Items.Refresh();

    或者,在完成对当前的选中项的操作之后,清除相应的selectedItemslstShow.SelectedItems.Clear();


    Lisa Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月24日 6:32
    版主
  • 我做了个测试,确实不是上面的Style的问题。

    这里补充一下:我的ListBox绑定的数据是自定义对象集合,不知道是不是和Equals、GetHashCode的实现有关。

    因为点击Button操作完之后调用lstShow.SelectedItems.Clear();不能清除选择的多个项,只能去除一项,而且有时候一项都不能去除。

    比如:1,第一次 选择三项,SelectedItems.Count=3

    2,点击Button后会去除最后一项,SelectedItems.Count=2

    3,第二次点击Button,SelectedItems.Count=2,调用lstShow.SelectedItems.Clear();SelectedItems.Count=2;

    4,再次勾选一项,点击Button,SelectedItems.Count=3,调用lstShow.SelectedItems.Clear();SelectedItems.Count=2;

    5,再次勾选三项,点击Button,SelectedItems.Count=5,调用lstShow.SelectedItems.Clear();SelectedItems.Count=5;

    6,再次勾选一项,点击Button,SelectedItems.Count=6,调用lstShow.SelectedItems.Clear();SelectedItems.Count=5;

    这个问题就让我开始怀疑是不是Equals、GetHashCode实现有问题了,因为我用ListBox绑定String[]数据集合测试时不会出现上面的问题,换成ObservableCollection<MyClass>就出现上面的问题了,这个问题困扰我几天了,不知道是不是MyClass的Equals、GetHashCode实现有问题呢?如果不是还有其他什么可能出问题的地方呢?

    2013年1月24日 14:11

全部回复

  • 你好,

    在看过了你的style代码后,我认为这个问题不是出在style部分,估计是你在别的地方对selected Item进行了设置。

    建议你在清除ItemsSource 或某个items之后对ListBoxitems进行刷新:

      lstShow.Items.Refresh();

    或者,在完成对当前的选中项的操作之后,清除相应的selectedItemslstShow.SelectedItems.Clear();


    Lisa Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月24日 6:32
    版主
  • 我做了个测试,确实不是上面的Style的问题。

    这里补充一下:我的ListBox绑定的数据是自定义对象集合,不知道是不是和Equals、GetHashCode的实现有关。

    因为点击Button操作完之后调用lstShow.SelectedItems.Clear();不能清除选择的多个项,只能去除一项,而且有时候一项都不能去除。

    比如:1,第一次 选择三项,SelectedItems.Count=3

    2,点击Button后会去除最后一项,SelectedItems.Count=2

    3,第二次点击Button,SelectedItems.Count=2,调用lstShow.SelectedItems.Clear();SelectedItems.Count=2;

    4,再次勾选一项,点击Button,SelectedItems.Count=3,调用lstShow.SelectedItems.Clear();SelectedItems.Count=2;

    5,再次勾选三项,点击Button,SelectedItems.Count=5,调用lstShow.SelectedItems.Clear();SelectedItems.Count=5;

    6,再次勾选一项,点击Button,SelectedItems.Count=6,调用lstShow.SelectedItems.Clear();SelectedItems.Count=5;

    这个问题就让我开始怀疑是不是Equals、GetHashCode实现有问题了,因为我用ListBox绑定String[]数据集合测试时不会出现上面的问题,换成ObservableCollection<MyClass>就出现上面的问题了,这个问题困扰我几天了,不知道是不是MyClass的Equals、GetHashCode实现有问题呢?如果不是还有其他什么可能出问题的地方呢?

    2013年1月24日 14:11
  • 目测你需要重载Equals方法, 我不是100%确定,我觉得重载Equals是可以解决的。

    如果不行, 给我提供一个完整的例子。


    Sheldon _Xiao
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月25日 4:32
    版主
  •     public class Test
        {
            public Test() { }
    
            public int Id { get; set; }
    
            public string TName { get; set; }
    
            public TestSeries TSeries { get; set; }
    
            public TestType TType { get; set; }
    
            public bool IsComplete { get; set; }
    
            public string Remark { get; set; }
    
            public override bool Equals(object obj)
            {
                if (this == obj) return true;
    
                if (obj == null || this.GetType() != obj.GetType())
                {
                    return false;
                }
    
                Test hb = (Test)obj;
    
                if (this.TSeries == null)
                {
                    if (hb.TSeries != null)
                    {
                        return false;
                    }
                }
                else
                {
                    if (!this.TSeries.Equals(hb.TSeries))
                    {
                        return false;
                    }
                }
    
                if (this.TType == null)
                {
                    if (hb.TType != null)
                    {
                        return false;
                    }
                }
                else
                {
                    if (!this.TType.Equals(hb.TType))
                    {
                        return false;
                    }
                }
    
                return ((this.Id == hb.Id) && (this.TName == hb.TName)
                                          && (this.Remark == hb.Remark)
                                          && (this.IsComplete == hb.IsComplete)
                                          );
            }
    
            public override int GetHashCode()
            {
                int HashCodeId = this.Id;
                int HashCodeTName = this.TName == null ? 0 : this.TName.GetHashCode();
                int HashCodeTSeries = this.TSeries == null ? 0 : this.TSeries.GetHashCode();
                int HashCodeTType = this.TType == null ? 0 : this.TType.GetHashCode();
                int HashCodeRemark = this.Remark == null ? 0 : this.Remark.GetHashCode();
                int HashCodeIsComplete = this.IsComplete.GetHashCode();
    
                return HashCodeId ^ HashCodeTName ^ HashCodeTSeries ^ HashCodeTType ^ HashCodeRemark ^ HashCodeIsComplete;
            }
        }
    

    这是我的类中的一个,我的这些数据类都重载了Equals和GetHashCode实现方法都和这个是一样的,你看这个实现有问题吗?
    2013年1月28日 3:06
  • 就是重载GetHashCode有问题,可是不知道问题在那儿,不重载GetHashCode就正常了
    2013年1月28日 5:26
  • 我觉得你hashcode的方法有点小问题就是 object是null和0的时候 hashcode是一样的, 但我觉得这个跟你的问题没多大关系。

    你可以再试试,如果问题还是村子,你能给我个重现的例子么


    Sheldon _Xiao
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月28日 6:08
    版主
  • 重现问题的例子弄好了,怎么给你呢?
    2013年1月28日 8:02
  • 上传到skydrive上吧

    1) type "skydrive.live.com" in the IE address bar.
    2) sign in your account on the page, then click add files to upload your files(remember upload as "public").
    3) give me download link after upload successfully.


    Sheldon _Xiao
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月28日 8:20
    版主
  • 我还是直接贴出来吧
    public class Test
        {
            public Test() { }
    
            public int Id { get; set; }
    
            public string TName { get; set; }
    
            public bool IsComplete { get; set; }
    
            public string Remark { get; set; }
    
            public override bool Equals(object obj)
            {
                if (this == obj) return true;
    
                if (obj == null || this.GetType() != obj.GetType())
                {
                    return false;
                }
    
                Test t = (Test)obj;
    
                return ((this.Id == t.Id) && (this.TName == t.TName)
                                         && (this.Remark == t.Remark)
                                         && (this.IsComplete == t.IsComplete)
                                         );
            }
    
            public override int GetHashCode()
            {
                int HashCodeId = this.Id;
                int HashCodeTName = this.TName == null ? 0 : this.TName.GetHashCode();
                int HashCodeRemark = this.Remark == null ? 0 : this.Remark.GetHashCode();
                int HashCodeIsComplete = this.IsComplete.GetHashCode();
    
                return HashCodeId ^ HashCodeTName ^ HashCodeRemark ^ HashCodeIsComplete;
            }
        }
    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Button Content="获取数据1" Height="23" HorizontalAlignment="Left" Margin="12,38,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
            <Button Content="获取数据2" Height="23" HorizontalAlignment="Left" Margin="12,82,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="button2_Click" />
            <ListBox Name="lstTestData"  Height="177" HorizontalAlignment="Left" Margin="127,38,0,0" VerticalAlignment="Top" Width="120" 
                     DisplayMemberPath="TName"/>
            <GroupBox Header="详细信息"  Height="176" HorizontalAlignment="Left" Margin="288,39,0,0" Name="groupBox1" VerticalAlignment="Top" Width="200">
                <Grid Name="gridDetailed"  DataContext="{Binding SelectedItem, ElementName=lstTestData,Mode=OneWay}">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="67*" />
                        <ColumnDefinition Width="121*" />
                    </Grid.ColumnDefinitions>
                    <TextBox Height="23" Text="{Binding Path=TName}"  HorizontalAlignment="Left" Margin="21,19,0,0" Name="textBox1" VerticalAlignment="Top" Width="87" Grid.Column="1" />
                    <Label Content="TName:" Height="28" HorizontalAlignment="Left" Margin="21,15,0,0" Name="label1" VerticalAlignment="Top" Grid.ColumnSpan="2" />
                    <CheckBox Name="cbIsComplete"  Content="是否完成" IsChecked="{Binding Path=IsComplete}"  Height="16" HorizontalAlignment="Left" Margin="21,66,0,0" VerticalAlignment="Top" Grid.Column="1" />
                    <Button Content="更新" Height="23" HorizontalAlignment="Left" Margin="24,121,0,0" Name="button3" VerticalAlignment="Top" Width="75" Click="button3_Click" Grid.Column="1" />
                </Grid>
            </GroupBox>
        </Grid>
    </Window>
    

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Collections.ObjectModel;
    
    namespace WpfApplication1
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                ObservableCollection<Test> data = new ObservableCollection<Test>();
                for (int i = 0; i < 6; i++)
                {
                    Test t = new Test()
                    {
                        Id = i,
                        IsComplete = false,
                        TName = i.ToString(),
                    };
                    data.Add(t);
                }
                lstTestData.ItemsSource = data;
            }
    
            private void button2_Click(object sender, RoutedEventArgs e)
            {
                ObservableCollection<Test> data = new ObservableCollection<Test>();
                for (int i = 0; i < 8; i++)
                {
                    Test t = new Test()
                    {
                        Id = 10 + i,
                        IsComplete = true,
                        TName = (10 + i).ToString(),
                    };
                    data.Add(t);
                }
                lstTestData.ItemsSource = data;
            }
    
            private void button3_Click(object sender, RoutedEventArgs e)
            {
                Test test = gridDetailed.DataContext as Test;
                if (test!=null)
                {
                    test.IsComplete = cbIsComplete.IsChecked.HasValue ? cbIsComplete.IsChecked.Value : false;
                }
            }
        }
    }
    

    1,点击获取数据。(这是listbox出现了构造的数据项)
    2,listbox中选择一项。(这时对应的详细信息框中相应的信息出现)
    3,修改“是否完成”,原本是没有选择,现在选择,然后点击“更新”
    4,再回到list选择其他任一项
    5,再次选择修改项
    6,再次选择其他任何一项,这时就会出现异常

    在Test类中不重载GetHashCode就不会出现这个问题了,我很纠结这是为什么?

    还有就是重载GetHashCode有没有什么比较好的参考?


    2013年1月28日 8:22
  • 好的,我现在忙,等会儿看你这个问题。


    Sheldon _Xiao
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月28日 8:31
    版主
  • 我看你的代码了,是这样, 我们推荐的是1个帖子讨论一个问题,我阅读了你最开始发帖子的问题:

    --〉然后,lstShow.ItemsSource=null;清除掉ListBox显示的内容,但是此时如果再次点击Button,仍然可以通过lstShow.SelectedItems获取到上次选中的项,这里让我很郁闷

    我们要解决的是这个问题, 希望你能给我一个可以重现这种情况的例子。


    Sheldon _Xiao
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月28日 10:21
    版主
  • 我看你的代码了,是这样, 我们推荐的是1个帖子讨论一个问题,我阅读了你最开始发帖子的问题:

    --〉然后,lstShow.ItemsSource=null;清除掉ListBox显示的内容,但是此时如果再次点击Button,仍然可以通过lstShow.SelectedItems获取到上次选中的项,这里让我很郁闷

    我们要解决的是这个问题, 希望你能给我一个可以重现这种情况的例子。


    Sheldon _Xiao
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    这个问题找到了,是因为我对lstShow.SelectedItems的项的数据进行了修改因此导致对应的对象有所变化,所以lstShow.SelectedItems.Clear();不能清除选择项
    2013年1月28日 12:29
  • <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <Style x:Key="CheckBoxListStyle" TargetType="{x:Type ListBox}">
                <Setter Property="SelectionMode" Value="Multiple"></Setter>
                <Setter Property="ItemContainerStyle">
                    <Setter.Value>
                        <Style TargetType="{x:Type ListBoxItem}">
                            <Setter Property="Margin" Value="2"></Setter>
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                        <CheckBox Focusable="False"
                                                  IsChecked="{Binding Path=IsSelected,Mode=TwoWay,
                                            RelativeSource={RelativeSource TemplatedParent}}">
                                            <ContentPresenter></ContentPresenter>
                                        </CheckBox>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </Setter.Value>
                </Setter>
            </Style>
        </Window.Resources>
        <Grid>
            <Button Content="获取数据1" Height="23" HorizontalAlignment="Left" Margin="22,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
            <ListBox Name="lstTestData" Style="{StaticResource CheckBoxListStyle}"  Height="199" HorizontalAlignment="Left" Margin="21,41,0,0" VerticalAlignment="Top" Width="76" 
                     DisplayMemberPath="TName"/>
            <Button Content="Add" Height="23" HorizontalAlignment="Left" Margin="22,262,0,0" Name="button3" VerticalAlignment="Top" Width="75" Click="button3_Click_1" />
            <DataGrid Name="gridShowTest"  AutoGenerateColumns="False" Height="304" HorizontalAlignment="Left" Margin="123,0,0,0" VerticalAlignment="Top" Width="380" >
                <DataGrid.Columns>
                    <DataGridTextColumn Header="编号" Binding="{Binding Path=Id}"/>
                    <DataGridTextColumn Header="名称" Binding="{Binding Path=TName}"/>
                    <DataGridCheckBoxColumn Header="是否完成" Binding="{Binding Path=IsComplete}"/>
                    <DataGridTextColumn Header="备注" Binding="{Binding Path=Remark}"/>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>
    

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Collections.ObjectModel;
    
    namespace WpfApplication1
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                ObservableCollection<Test> data = new ObservableCollection<Test>();
                for (int i = 0; i < 10; i++)
                {
                    Test t = new Test()
                    {
                        Id = i,
                        IsComplete = false,
                        TName = i.ToString(),
                        Remark = "备注" + i.ToString()
                    };
                    data.Add(t);
                }
                lstTestData.ItemsSource = data;
            }
    
            private void button3_Click_1(object sender, RoutedEventArgs e)
            {
                ObservableCollection<Test> addTests = new ObservableCollection<Test>();
                foreach (Test t in lstTestData.SelectedItems)
                {
                    t.IsComplete = true;
                    gridShowTest.Items.Add(t);
                    addTests.Add(t);
                }
    
                IEnumerable<Test> items = lstTestData.ItemsSource.OfType<Test>();
                ObservableCollection<Test> remainSeeds = new ObservableCollection<Test>(items);
                foreach (Test t in addTests)
                {
                    remainSeeds.Remove(t);
                }
                lstTestData.SelectedItems.Clear();
                lstTestData.ItemsSource = remainSeeds;
            }
        }
    }
    

    选择Listbox的项后,点击添加会添加项到DataGrid,再次点击时选择项还在,想这样的情况该怎么做比较好呢?
    2013年1月28日 12:34
  • 我还是直接贴出来吧
    public class Test
        {
            public Test() { }
    
            public int Id { get; set; }
    
            public string TName { get; set; }
    
            public bool IsComplete { get; set; }
    
            public string Remark { get; set; }
    
            public override bool Equals(object obj)
            {
                if (this == obj) return true;
    
                if (obj == null || this.GetType() != obj.GetType())
                {
                    return false;
                }
    
                Test t = (Test)obj;
    
                return ((this.Id == t.Id) && (this.TName == t.TName)
                                         && (this.Remark == t.Remark)
                                         && (this.IsComplete == t.IsComplete)
                                         );
            }
    
            public override int GetHashCode()
            {
                int HashCodeId = this.Id;
                int HashCodeTName = this.TName == null ? 0 : this.TName.GetHashCode();
                int HashCodeRemark = this.Remark == null ? 0 : this.Remark.GetHashCode();
                int HashCodeIsComplete = this.IsComplete.GetHashCode();
    
                return HashCodeId ^ HashCodeTName ^ HashCodeRemark ^ HashCodeIsComplete;
            }
        }
    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Button Content="获取数据1" Height="23" HorizontalAlignment="Left" Margin="12,38,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
            <Button Content="获取数据2" Height="23" HorizontalAlignment="Left" Margin="12,82,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="button2_Click" />
            <ListBox Name="lstTestData"  Height="177" HorizontalAlignment="Left" Margin="127,38,0,0" VerticalAlignment="Top" Width="120" 
                     DisplayMemberPath="TName"/>
            <GroupBox Header="详细信息"  Height="176" HorizontalAlignment="Left" Margin="288,39,0,0" Name="groupBox1" VerticalAlignment="Top" Width="200">
                <Grid Name="gridDetailed"  DataContext="{Binding SelectedItem, ElementName=lstTestData,Mode=OneWay}">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="67*" />
                        <ColumnDefinition Width="121*" />
                    </Grid.ColumnDefinitions>
                    <TextBox Height="23" Text="{Binding Path=TName}"  HorizontalAlignment="Left" Margin="21,19,0,0" Name="textBox1" VerticalAlignment="Top" Width="87" Grid.Column="1" />
                    <Label Content="TName:" Height="28" HorizontalAlignment="Left" Margin="21,15,0,0" Name="label1" VerticalAlignment="Top" Grid.ColumnSpan="2" />
                    <CheckBox Name="cbIsComplete"  Content="是否完成" IsChecked="{Binding Path=IsComplete}"  Height="16" HorizontalAlignment="Left" Margin="21,66,0,0" VerticalAlignment="Top" Grid.Column="1" />
                    <Button Content="更新" Height="23" HorizontalAlignment="Left" Margin="24,121,0,0" Name="button3" VerticalAlignment="Top" Width="75" Click="button3_Click" Grid.Column="1" />
                </Grid>
            </GroupBox>
        </Grid>
    </Window>

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Collections.ObjectModel;
    
    namespace WpfApplication1
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                ObservableCollection<Test> data = new ObservableCollection<Test>();
                for (int i = 0; i < 6; i++)
                {
                    Test t = new Test()
                    {
                        Id = i,
                        IsComplete = false,
                        TName = i.ToString(),
                    };
                    data.Add(t);
                }
                lstTestData.ItemsSource = data;
            }
    
            private void button2_Click(object sender, RoutedEventArgs e)
            {
                ObservableCollection<Test> data = new ObservableCollection<Test>();
                for (int i = 0; i < 8; i++)
                {
                    Test t = new Test()
                    {
                        Id = 10 + i,
                        IsComplete = true,
                        TName = (10 + i).ToString(),
                    };
                    data.Add(t);
                }
                lstTestData.ItemsSource = data;
            }
    
            private void button3_Click(object sender, RoutedEventArgs e)
            {
                Test test = gridDetailed.DataContext as Test;
                if (test!=null)
                {
                    test.IsComplete = cbIsComplete.IsChecked.HasValue ? cbIsComplete.IsChecked.Value : false;
                }
            }
        }
    }

    1,点击获取数据。(这是listbox出现了构造的数据项)
    2,listbox中选择一项。(这时对应的详细信息框中相应的信息出现)
    3,修改“是否完成”,原本是没有选择,现在选择,然后点击“更新”
    4,再回到list选择其他任一项
    5,再次选择修改项
    6,再次选择其他任何一项,这时就会出现异常

    在Test类中不重载GetHashCode就不会出现这个问题了,我很纠结这是为什么?

    还有就是重载GetHashCode有没有什么比较好的参考?


    问题出在这里:

    test.IsComplete = cbIsComplete.IsChecked.HasValue ? cbIsComplete.IsChecked.Value : false;

    你不能改变ObservableCollection<T>里面的对象的状态,而不进行通知(实现一个PropertyChanged事件看看?),这可能导致问题出现。

    除了尝试为IsComplete添加PropertyChanged的通知,还尝试下面的内容:

    让GetHashCode总是返回特定的值,例如总是返回0,看看是否有问题。

    我认为是因为你在这里修改了里面的对象的状态,但是外部看不见这个变化,而在这坨里面的有一个实现用到了GetHashCode,这就有问题,Hash值变化了但是并没有通知这个使用GetHashCode的组件。

    2013年1月28日 15:00
  • 问题出在这里:

    test.IsComplete = cbIsComplete.IsChecked.HasValue ? cbIsComplete.IsChecked.Value : false;

    你不能改变ObservableCollection<T>里面的对象的状态,而不进行通知(实现一个PropertyChanged事件看看?),这可能导致问题出现。

    除了尝试为IsComplete添加PropertyChanged的通知,还尝试下面的内容:

    让GetHashCode总是返回特定的值,例如总是返回0,看看是否有问题。

    我认为是因为你在这里修改了里面的对象的状态,但是外部看不见这个变化,而在这坨里面的有一个实现用到了GetHashCode,这就有问题,Hash值变化了但是并没有通知这个使用GetHashCode的组件。

    1,添加PropertyChanged的通知问题依然存在。

    2,让GetHashCode总是返回特定的值 或者 不重载GetHashCode问题就不出现了

    是不是说明我的这个GetHashCode重载有问题呢?请指教

    2013年1月31日 7:29
  • 是的, 我一直觉得你GetHashCode有问题,但是具体问题我还说不出来, 我个人觉得你写的没问题,但是我也没弄明白为什么你的

    ^ HashCodeIsComplete;
    会出问题。


    Sheldon _Xiao
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年1月31日 8:50
    版主
  • 问题出在这里:

    test.IsComplete = cbIsComplete.IsChecked.HasValue ? cbIsComplete.IsChecked.Value : false;

    你不能改变ObservableCollection<T>里面的对象的状态,而不进行通知(实现一个PropertyChanged事件看看?),这可能导致问题出现。

    除了尝试为IsComplete添加PropertyChanged的通知,还尝试下面的内容:

    让GetHashCode总是返回特定的值,例如总是返回0,看看是否有问题。

    我认为是因为你在这里修改了里面的对象的状态,但是外部看不见这个变化,而在这坨里面的有一个实现用到了GetHashCode,这就有问题,Hash值变化了但是并没有通知这个使用GetHashCode的组件。

    1,添加PropertyChanged的通知问题依然存在。

    2,让GetHashCode总是返回特定的值 或者 不重载GetHashCode问题就不出现了

    是不是说明我的这个GetHashCode重载有问题呢?请指教


    尝试去掉IsComplete对HasCode的影响。
    2013年1月31日 11:49