4
votes

I currently have an Entity that has a collection property on it. 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.

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;

My Mainwindow

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

My listbox structure

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

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

I select the first object, the event fires, I select the second object, the event fires, I select the first object, the event doesn't fire, I select third object, the event fires. It seems like it only triggers and calls the event once.

My XAML Code:

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

The test method is just an empty method I just want to hit the breakpoint every time I change.

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

Update 1: I tried to reproduce this in a simple WPF app, it seems that the ListBoxItem is getting IsEnabled to false but I snooped it and all the controls are enabled. It just getting a grey background that looks like disabled. Will try to investigate further.

Update 2: It seems that the ListBoxItem IsSelected property is not being unset when you change an item.

3
I do not understand how the c# code is related to the XAML. You might want to be more precise.JohnB
Gave you the structure of the Entity that's why I have the C# code there, the xaml is how I bind it. It triggers fine and I tried reproducing it with different normal entities and it behaves the same.123 456 789 0
You should post the code of your method "Test". I have a hard time believing this method doesn't run under the circumstances you are describing. You may not be getting the results you expect but that could be because of a flaw in the logic of the method. Did you try putting a breakpoint in "Test"?Lee O.
Yes, I don't need to put the method for Test cause it is just empty method I just want it to fire. I did put a breakpoint.123 456 789 0
@DisplayNameismissing i know this is an very old post but doesn't fit my answer your question?WiiMaxx

3 Answers

6
votes

To answer your question ...

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.

... in a learning by doing way

open a new WPF Project add 2 Listboxes create ONE SelectionChanged event for both and add some items to each Listbox

let's mention it look's now like this

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

If you now select Element1 in listBox1 your listBox_SelectionChanged get triggert after that select Element2 in your listBox2 so your listBox_SelectionChanged get's triggert again.

If you take a closer look at your listBox1 you will see that the Background behind your Element1 is gray which means it is selected, but with out focuse. If you select now the Element1 in your listBox1 again the listBox_SelectionChanged doesn't get triggert because the selection does't change only the Focuse does.

That's the exact same "problem" is in your code because your DataTemplate does the same think we did as we added our 2 Listboxes just automatically

as simple and dirt workaround you could use the following code

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

The simple solution I found out is to make selectedItem as null in the event handler.

private void tempList_SelectionChanged(object sender, SelectionChangedEventArgs e)

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

Selecting the same item is not a SelectionChanged event. The selection did not change.

The problem statement is not clear.

Break it down. This works for me. If I select any item a second time, 3rd, 4th time the event fires.

OP asserted it does not work if it is a List in a List. Still works for me.

    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>