c# - WPF 列表框选择已更改

标签 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 属性似乎没有被取消设置。

最佳答案

回答你的问题...

I want to know if why would the SelectionChanged only fire once and it won't trigger the SelectionChanged again once I try to select the item that was previously selected.

...边做边学

打开一个新的 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;

如果您现在在 listBox1 中选择 Element1 您的 listBox_SelectionChanged 会在您的 中选择 Element2 之后触发>listBox2 因此您的 listBox_SelectionChanged 再次触发。

如果你仔细看看你的 listBox1 你会看到你的 Element1 后面的 Background 是灰色的,这意味着它被选中了,但没有重点。如果您现在再次选择 listBox1 中的 Element1,则 listBox_SelectionChanged 不会触发,因为选择不会更改,只有 Focuse 会更改。

这与您的代码中存在完全相同的“问题”,因为您的 DataTemplate 与我们自动添加 2 个列表框的想法相同

作为简单而肮脏的解决方法,您可以使用以下代码

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

关于c# - WPF 列表框选择已更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10787415/

相关文章:

c# - i7 多核处理器上的 .Net 3.5

c# - MVC 添加记录到数据库

c# - 从 WPF 项目创建单个 Exe 文件

c# - 如何保持更新的对象列表框?

c# - 货币文化格式不适用于 DataGridView 列

wpf - 不同用户控件中的WPF命令处理

c# - MVVM light RelayCommand 触发两次

asp.net - Jquery 列表框/文本框过滤器

silverlight - 如何在 ListBox 中的项目之间显示分隔线?

c# - 处理异步函数的空响应的正确方法是什么?