WPF列表框SelectionChanged

时间:2012-05-28 15:59:59

标签: c# wpf listbox

我目前有一个Entity,上面有一个集合属性。我想知道为什么SelectionChanged只会触发一次,一旦我尝试选择之前选择的项目,它就不会再触发SelectionChanged

MainWindowViewModel

  public MainWindowViewModel()
    {
        var a = new List<Test>();

        a.Add(new Test() { Name = "Leo", Test1 = new List<Test1> { new Test1() { Content = "aaa"} } });
        a.Add(new Test() { Name = "2", Test1 = new List<Test1> { new Test1() { Content = "bbb"} } });
        a.Add(new Test() { Name = "Le33o", Test1 = new List<Test1> { new Test1() { Content = "ccc"} } });
        A = a;
    }

    private List<Test> _a;
    public List<Test> A
    {
        get { return _a; }
        set { _a = value; OnPropertyChanged("A");}
    }

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

我的主窗口

public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
        }
        private void Test(object sender, SelectionChangedEventArgs e)
        {
        }

我的列表框结构

public class Test
{
    public List<Test1> Test1 { get; set; }
    public string Name
    {
        get;set;
    }
}

public class Test1
{
    public string Content { get; set; }
}

我选择第一个对象,事件触发,我选择第二个对象,事件触发,我选择第一个对象,事件不触发,我选择第三个对象,事件触发。它似乎只触发并调用一次事件。

我的XAML代码:

<ItemsControl x:Name="Lists" ItemsSource="{Binding A}" Grid.Row="1">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Name}" FontWeight="Bold" 
                                                        Style="{StaticResource DefaultTextBlockStyle}" />

                    <ListBox  SelectionChanged="Test"  ItemsSource="{Binding Test1}"
                                 Margin="5,0,0,0" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding Content}" />
                                </StackPanel>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

测试方法只是一个空方法,我只想在每次更改时点击断点。

  private void Test(object sender, SelectionChangedEventArgs e)
    {
    }

更新1 :我试图在一个简单的WPF应用程序中重现这一点,似乎ListBoxItem使IsEnabled变为false但我已经窥探它并启用了所有控件。它只是得到一个看起来像残疾人的灰色背景。将尝试进一步调查。

更新2 :更改项目时似乎未取消设置ListBoxItem IsSelected属性。

3 个答案:

答案 0 :(得分:5)

回答你的问题...

  

我想知道为什么SelectionChanged只会触发一次,一旦我尝试选择它,它就不会再次触发SelectionChanged   之前选择的项目。

......在实践中学习

打开一个新的WPF项目添加2个列表框为两个创建一个SelectionChanged事件并向每个列表框添加一些项目

让我们提一下它现在就像这样

    <ListBox Height="100" Name="listBox1" Width="120" SelectionChanged="listBox_SelectionChanged"/>
    <ListBox Height="100" Name="listBox2" Width="120" SelectionChanged="listBox_SelectionChanged"/>

        var list = new List<string>();
        list.Add("Element1");
        list.Add("Element2");
        list.Add("Element3");
        list.Add("Element4");

        listBox1.ItemsSource = list;
        listBox2.ItemsSource = list;

如果现在选择Element1 listBox1 listBox_SelectionChanged获取触发后的Element2,请在listBox2中选择listBox_SelectionChanged,以便listBox1获取触发器试。

如果仔细查看Background,您会看到Element1后面的Element1是灰色的,这意味着它已被选中,但没有注意到。如果您现在再次选择listBox1中的listBox_SelectionChanged,则DataTemplate不会获得触发因为选择不会仅改变Focuse。

您的代码中存在完全相同的“问题”,因为您 private object seletedItem; private ListBox ItemsHost; private void Test(object sender, SelectionChangedEventArgs e) { var buff = sender as ListBox; if (seletedItem != null) if (ItemsHost != buff) ItemsHost.SelectedItem = null; ItemsHost = buff; if (e.AddedItems.Count > 0) seletedItem = e.AddedItems[0]; } 的做法与我们自动添加2个列表框时的做法相同

简单易用的解决方法您可以使用以下代码

{{1}}

答案 1 :(得分:0)

我发现的简单解决方案是在事件处理程序中将selectedItem设为null

private void tempList_SelectionChanged(object sender, SelectionChangedEventArgs e)

{    
    Card selectedOffer = (TempList.SelectedItem as Card);
    if (selectedOffer != null)
    {
        MessageBox.Show(selectedOffer._id);
    }
    ListBoxNeeded.SelectedItem = null;
}

答案 2 :(得分:-4)

选择相同的项目不是SelectionChanged事件。选择没有改变。

问题陈述不明确。

分解。这适合我。如果我第二次选择任何项目,第3次,第4次事件发生。

OP断言如果它是列表中的列表则不起作用。仍然适合我。

    public MainWindow()
        {
            this.DataContext = this;
            InitializeComponent();
        }

        public List<ListList> ListList1 
        {
            get { return new List<ListList>{new ListList("name1", new List<string> { "one", "two", "three" })}; } 
        }

        private void Test(object sender, SelectionChangedEventArgs e)
        {
            ListBox lb = (ListBox)sender;
            System.Diagnostics.Debug.WriteLine(lb.SelectedItem.ToString());
        }

        public class ListList
        {
            public string Name { get;  set; }
            public List<string> Values { get;  set; }
            public ListList(string name, List<string> values) { Name = name; Values = values; }
        }

<ListBox ItemsSource="{Binding Path=ListList1}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <ListBox  SelectionChanged="Test" ItemsSource="{Binding Path=Values}">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding}" />
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>