Skip to main content

Microsoft Silverlight

Answered Question Listbox SelectionChanged not firing for previously selected itemsRSS Feed

(0)

Petunya
Petunya

Member

Member

42 points

35 Posts

Listbox SelectionChanged not firing for previously selected items

Hello,

I have a custom control adopted from Shawn Burke's blog (ExpandoHeaderControl).  I used his tutorial for a guide and Expression Blend June Preview to create a control like a typical drop-down.

I switched to Beta 2 today and ended up putting the drop-down content of the control into a popup (it was always showing behind my other controls in the page and I couldn't find any other way to fix that).  The content happens to be a listbox.

I noticed that if, for example, I do the following:

 1. Click itemA
 2. Click itemB
 3. Click itemA again.

The selection changed event gets thrown for steps 1 and 2, but not for step 3 (the handler below is only called for steps 1 and 2).

Below are snippets of my code and XAML, in case it helps clarify how everything is put together:

SelectionChanged Event Handler:

void lbChallenges_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
           
selectedChallenge = (ChallengeServices.DChallenge)e.AddedItems[0];

            HeaderContentTB.Text = selectedChallenge.Name;
            MyDropDown.HideContent();

            challengeClient.GetChallengeParticipantsForChallengeAsync(selectedChallenge.ID);
            challengeClient.GetChallengeModesForChallengeAsync(selectedChallenge.ID);
        }

 

Below is a portion of the XAML for the control's template, in App.xaml:

<Popup x:Name="ContentPopup" VerticalOffset="83" HorizontalOffset="5" Width="{TemplateBinding Width}" Grid.Row="1" Margin="0,2,0,0" IsOpen="False">
    <Grid x:Name="grid" RenderTransformOrigin="0.5,0" Opacity="0" >
        <Grid.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform />
                                        <SkewTransform/>
                                        <RotateTransform/>
                                        <TranslateTransform/>
                                    </TransformGroup>
         </Grid.RenderTransform>
         <ContentControl Content="{TemplateBinding Content}" />
    </Grid>
</Popup>

 Below is how the custom control is being used, and the content is being set (in Page.xaml).  It is long, sorry:

 <my:DropDownControl x:Name="MyDropDown" Height="150" Width="175" Style="{StaticResource DropDownControlTemplate}" >
                    <my:DropDownControl.HeaderContent>
                        <TextBlock x:Name="HeaderContentTB" Text="SELECT CHALLENGE" Style="{StaticResource Verdana11}" />
                    </my:DropDownControl.HeaderContent>
                    
                    <ListBox x:Name="lbChallenges" Width="175" Height="100" Margin="3" DisplayMemberPath="Name" >
                        <ListBox.ItemContainerStyle>
                            <Style TargetType="ListBoxItem">
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="ListBoxItem">
                                            <Grid x:Name="RootElement" Background="Transparent" Margin="1">
                                                <vsm:VisualStateManager.VisualStateGroups>
                                                    <vsm:VisualStateGroup x:Name="CommonStates">
                                                        <vsm:VisualState x:Name="Normal" />
                                                        <vsm:VisualState x:Name="MouseOver">
                                                            <Storyboard>
                                                                <DoubleAnimation Storyboard.TargetName="Overlay" Storyboard.TargetProperty="Opacity" To=".25" Duration="0" />
                                                            </Storyboard>
                                                        </vsm:VisualState>
                                                    </vsm:VisualStateGroup>
                                                    <vsm:VisualStateGroup x:Name="SelectionStates">
                                                        <vsm:VisualState x:Name="Unselected" />
                                                        <vsm:VisualState x:Name="Selected">
                                                            <Storyboard>
                                                                <DoubleAnimation Storyboard.TargetName="Overlay" Storyboard.TargetProperty="Opacity" To=".75" Duration="0" />
                                                            </Storyboard>
                                                        </vsm:VisualState>
                                                    </vsm:VisualStateGroup>
                                                    <vsm:VisualStateGroup x:Name="FocusStates">
                                                        <vsm:VisualState x:Name="Focused">
                                                        </vsm:VisualState>
                                                        <vsm:VisualState x:Name="Unfocused">
                                                        </vsm:VisualState>
                                                    </vsm:VisualStateGroup>
                                                </vsm:VisualStateManager.VisualStateGroups>

                                                <Rectangle x:Name="Overlay" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="#FF8FCB07" Opacity="0"/>
                                                <ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" />
                                            </Grid>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </ListBox.ItemContainerStyle>
                        <ListBox.Template>
                            <ControlTemplate>
                                <Border Background="#FFFBFAFA" BorderThickness="1" BorderBrush="#FFD0CFCF" CornerRadius="5">
                                    <ScrollViewer HorizontalScrollBarVisibility="Disabled">
                                        <ItemsPresenter />
                                    </ScrollViewer>
                                </Border>
                            </ControlTemplate>
                        </ListBox.Template>
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Name}" Style="{StaticResource Verdana11}" />
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
</my:DropDownControl>

 I'm wondering if anybody else has encountered this issue, or has any ideas on what could be causing it?  Because I am stumped. Embarrassed

sladapter
sladapter

All-Star

All-Star

17441 points

3,172 Posts

Re: Listbox SelectionChanged not firing for previously selected items

see my post on this thread: 

http://silverlight.net/forums/t/17446.aspx 

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

snelldl
snelldl

Member

Member

148 points

141 Posts

Re: Listbox SelectionChanged not firing for previously selected items

I just tested the selectionchanged event in a listbox in a popup on an app that I have and I can click the 1st item, then the 3rd and then the 1st item again and it fires the selectionchanged event each time.

Petunya
Petunya

Member

Member

42 points

35 Posts

Answered Question

Re: Listbox SelectionChanged not firing for previously selected items

Thank you for your information.  It helped me rule out some things.  I believe I have found what was causing the issue, it could be a bug:

I noticed that the visual states of the listbox items were acting slightly odd.  When I selected an item, it would go to the selected state (visually, a dark green background) and the popup would close.  The next time I opened the popup, the selected item was still in selected state (dark green) and if I moused over it and then moused out of it, without clicking anything, the selected item's visual state would go to normal (unselected, no dark green).

That seemed strange, and so I figured that closing the popup while in the selection changed event handler of the LB was messing up the visual states or selected states somehow, or both.  So I removed the popup.IsOpen = false and just used a scale transformation on the contents of the popup to make their height 0.

This appears to be working.  Now the selection changed event is firing every time it's supposed to.  The only "quirk" now is the selected item is not maintaining its selected visual state (the dark green background) after the drop-down content is scaled down.  I've checked the LB and it is maintaining its selected item, however after everything is hidden and then expanded again, the dark green background is gone.  This isn't a huge deal, but it means something is still not working 100% correctly with the states.
 

xanoxate
xanoxate

Member

Member

85 points

23 Posts

Re: Listbox SelectionChanged not firing for previously selected items

Petunya:
This appears to be working.  Now the selection changed event is firing every time it's supposed to.  The only "quirk" now is the selected item is not maintaining its selected visual state (the dark green background) after the drop-down content is scaled down.  I've checked the LB and it is maintaining its selected item, however after everything is hidden and then expanded again, the dark green background is gone.  This isn't a huge deal, but it means something is still not working 100% correctly with the states.
 

If you want the item selection to persist you can use the Visibility of the Grid to control whether the list is displayed or not, I've done this, here is a fragment to demonstrate

page.xaml:

<UserControl x:Class="SilverlightApplication7.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Canvas x:Name="LayoutRoot" Background="White">

        <Button Height="20" Width="20" Click="ListClick"/>
        <Popup x:Name="popup">
            <Grid x:Name="grid">
                <ListBox x:Name="list" MouseLeave="ListLostFocus" MouseLeftButtonUp="ListSelected" Width="100">
                    <ListBoxItem Content="One"/>
                    <ListBoxItem Content="Two"/>
                    <ListBoxItem Content="Three" />
                    <ListBoxItem Content="Four" />
                </ListBox>
            </Grid>
        </Popup>

    </Canvas>
</UserControl>

page.xaml.cs:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace SilverlightApplication7
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            grid.Visibility = Visibility.Collapsed;
        }

        private void ListClick(object sender, RoutedEventArgs e)
        {
            popup.IsOpen = true;
            grid.Visibility = Visibility.Visible;
        }

        private void ListLostFocus(object sender, MouseEventArgs e)
        {
            grid.Visibility = Visibility.Collapsed;
        }

        private void ListSelected(object sender, MouseButtonEventArgs e)
        {
            grid.Visibility = Visibility.Collapsed;
        }

    }
}


CleverCoder
CleverCoder

Member

Member

203 points

157 Posts

Re: Listbox SelectionChanged not firing for previously selected items

 I am also seeing this same problem. I have a popup with a ListBox in it. The selected items never seem to deselect.. and I can't get the event to fire more than once for each item. I'm not sure how to apply the scale transform to the popup .. I guess I would need to lose the popup and then apply the scale transform to hide the list? *Yuck!*

Fishing for answers...

Thanks!
- Sean

Petunya
Petunya

Member

Member

42 points

35 Posts

Re: Listbox SelectionChanged not firing for previously selected items

 CleverCoder,

No need to ditch the Popup!  Here is my XAML and code.  Note that all you ditch is the use of "popup.IsOpen = false;" which is causing the problems.

This is my style for the entire control I made.  I have bolded the XAML that will interest you:

<Style TargetType="my:DropDownControl" x:Key="DropDownControlTemplate">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="my:DropDownControl">
                    <Grid x:Name="RootElement" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}">
                        <vsm:VisualStateManager.VisualStateGroups>
                            <vsm:VisualStateGroup x:Name="DisplayStates">
                                <vsm:VisualState x:Name="Open">
                                    <Storyboard>
                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="grid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="1"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="grid" Storyboard.TargetProperty="(UIElement.Opacity)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="1"/>
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>

                                </vsm:VisualState>
                                <vsm:VisualState x:Name="Closed">
                                    <Storyboard>
                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="grid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="0"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="grid" Storyboard.TargetProperty="(UIElement.Opacity)">
                                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                                            <SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="0"/>
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>

                                </vsm:VisualState>
                            </vsm:VisualStateGroup>
                        </vsm:VisualStateManager.VisualStateGroups>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="20"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                       
                        <Grid Margin="5,0,5,0" Height="20" Grid.Row="0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="30" />

                            </Grid.ColumnDefinitions>
                            <Border HorizontalAlignment="Stretch" Grid.Column="0" CornerRadius="5,0,0,5" BorderThickness="1,1,1,1" BorderBrush="#FFD0CFCF" >
                                <Border.Background>
                                    <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                                        <GradientStop Color="#FFFBFAFA"/>
                                        <GradientStop Color="#FFE6E5E5" Offset="1"/>
                                    </LinearGradientBrush>
                                </Border.Background>
                                <ContentPresenter Content="{TemplateBinding HeaderContent}" />
                            </Border>
                            <ToggleButton Grid.Column="1" Template="{StaticResource ToggleButtonControlTemplate1}" x:Name="ButtonElement"/>
                        </Grid>

                        <Popup x:Name="ContentPopup" VerticalOffset="83" HorizontalOffset="5" Width="{TemplateBinding Width}" Grid.Row="1" Margin="0,2,0,0" IsOpen="False">
                            <Grid x:Name="grid" RenderTransformOrigin="0.5,0" Opacity="0" >
                                <Grid.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform />
                                        <SkewTransform/>
                                        <RotateTransform/>
                                        <TranslateTransform/>
                                    </TransformGroup>
                                </Grid.RenderTransform>
                                <ContentControl Content="{TemplateBinding Content}" />
                            </Grid>
                        </Popup>

                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

 

Then in the code file for this control, I have a HideContent() that says "VisualStateManager.GoToState(this, "Closed", true);" and ShowContent is similar, going to the "Opened" visual state.

I did read another suggestion that was to change the visibility of the grid nested inside the popup, from Visible to Collapsed and vice versa, though I did not try it because I wanted the animation that looks like it is "dropping down".

Let me know if you have any questions and I'll help you get this working. 

CleverCoder
CleverCoder

Member

Member

203 points

157 Posts

Re: Re: Listbox SelectionChanged not firing for previously selected items

 That worked beautifully. I like it. :) The only issue I have now is that the items don't seem to be selectable!... No effects and no select event. Very strange. Gotta run now, but thanks for the help!!!

Petunya
Petunya

Member

Member

42 points

35 Posts

Re: Re: Listbox SelectionChanged not firing for previously selected items

 I think that might be a different issue.  What do your listboxitems consist of?  I had a problem with hyperlinks in my listboxitems, where the hyperlinkbutton click event was not firing (except for the selected item), nor was the selectionchanged event firing if I clicked in a hyperlinkbutton's area (however clicking in the same listboxitem, outside the hyperlinkbutton area, would fire the listbox selection changed event).

When you have time, maybe you can post some of your XAML and code and we can try to figure it out?

CleverCoder
CleverCoder

Member

Member

203 points

157 Posts

Re: Re: Listbox SelectionChanged not firing for previously selected items

Just narrowed  the issue... I had some event handlers tied to a LayoutUpdated event of an adjacent button on the same page that would reposition the popup. I commented this out and it fixed the issue. Yikes! Seems like some sort of threading issue that blows up the list. I'm doing more investigation..hmmm...

CleverCoder
CleverCoder

Member

Member

203 points

157 Posts

Re: Re: Listbox SelectionChanged not firing for previously selected items

 I think I found the root issue. After switching the popup to be initially closed, instead of open (and contents hidden), the problems went away!  I modified my button handler so that it opens the popup the first time the button is clicked (and it's left open). This, combined with the solution above (thanks Petunya!) has given me a workable solution.  I still hope to see the issues with the Popup and/or ListBox fixed. I think the important thing to take away from this is to leave the popup closed while everything initializes, and open at the last minute before it's needed. Of course, if the child controls work properly and you're using a traditional - usually closed - popup model, you probably won't have any issues..

Cheers!
-Sean

ronaldeekelder
ronaldee...

Member

Member

26 points

12 Posts

Re: Re: Listbox SelectionChanged not firing for previously selected items

Another workaround might be to create a button in every listboxitem and react to the click events of the buttons.

Ronald Eekelder
www.OakReFactory.com
  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities