I’m currently playing with the Silverlight(Beta 2) Datagrid control. Before I wired up the SelectionChanged event, the grid would sort perfectly by clicking on the header. Now, when the grid is clicked, it will fire the SelectionChanged event when I click the header to sort. Is there any way around this?
In a semi-related topic, I’d like to have the SelectionChanged event fire when I click on an already selected item (so that I can have a pop-up occur to allow the user to edit the selected value). Right now, you have to click on a different value and then back to the value you wanted in order for it to pop up. Is there another way?
Included is my code.
The Page:
<UserControl x:Class='WebServicesApp.Page' xmlns='http://schemas.microsoft.com/client/2007' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:data='clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data' Width='1280' Height='1024' xmlns:d='http://schemas.microsoft.com/expression/blend/2008' xmlns:mc='http://schemas.openxmlformats.org/markup-compatibility/2006' mc:Ignorable='d'> <Grid x:Name='LayoutRoot' Background='White'> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <StackPanel Grid.Row='0' x:Name='OurStack' Orientation='Vertical' Margin='5,5,5,5'> <ContentControl VerticalAlignment='Center' HorizontalAlignment='Center'> <StackPanel x:Name='SearchStackPanel' Orientation='Horizontal' Margin='5,5,5,5'> <TextBlock x:Name='SearchEmail' HorizontalAlignment='Stretch' VerticalAlignment='Center' Text='Email Address:' Margin='5,5,5,5' /> <TextBox x:Name='InputText' HorizontalAlignment='Stretch' VerticalAlignment='Center' Width='150' Height='Auto' Margin='5,5,5,5'/> <Button x:Name='SearchButton' Content='Search' Click='CallServiceButton_Click' HorizontalAlignment='Center' VerticalAlignment='Center' Width='75' Height='Auto' Background='#FFAFAFAF' Margin='5,5,5,5'/> </StackPanel> </ContentControl> <Grid x:Name='DisplayRoot' Background='White' ShowGridLines='True' HorizontalAlignment='Center' VerticalAlignment='Center' MaxHeight='300' MinHeight='100' MaxWidth='800' MinWidth='200' ScrollViewer.HorizontalScrollBarVisibility='Visible' ScrollViewer.VerticalScrollBarVisibility='Visible'> <data:DataGrid ItemsSource='{Binding ''}' CanUserReorderColumns='False' CanUserResizeColumns='False' AutoGenerateColumns='False' AlternatingRowBackground='#FFAFAFAF' SelectionMode='Single' HorizontalAlignment='Center' VerticalAlignment='Center' Margin='5,5,5,5' x:Name='IncidentGrid' SelectionChanged='IncidentGrid_SelectionChanged'> <data:DataGrid.Columns> <data:DataGridTextColumn DisplayMemberBinding='{Binding Address}' Header='Email Address' IsReadOnly='True' /> <!--Width='150'--> <data:DataGridTextColumn DisplayMemberBinding='{Binding whereClause}' Header='Where Clause' IsReadOnly='True' /> <!--Width='500'--> <data:DataGridTextColumn DisplayMemberBinding='{Binding Enabled}' Header='Enabled' IsReadOnly='True' /> </data:DataGrid.Columns> </data:DataGrid> </Grid> </StackPanel> <Grid x:Name='EditPersonPopupGrid' Visibility='Collapsed'> <Rectangle HorizontalAlignment='Stretch' VerticalAlignment='Stretch' Opacity='0.765' Fill='#FF8A8A8A' /> <Border CornerRadius='30' Background='#FF2D1DCC' Width='700' Height='400' HorizontalAlignment='Center' VerticalAlignment='Center' BorderThickness='1,1,1,1' BorderBrush='#FF000000'> <StackPanel x:Name='EditPersonStackPanel' Orientation='Vertical' Background='White' HorizontalAlignment='Center' VerticalAlignment='Center' Width='650' > <ContentControl> <StackPanel x:Name='EmailEditStackPanel' Orientation='Horizontal'> <TextBlock Text='Email Address:' Width='200' Margin='5,0,5,0' /> <TextBox x:Name='EmailPopupTextBox' Width='200' /> </StackPanel> </ContentControl> <ContentControl> <StackPanel x:Name='AppliesToDropdownStackPanel' Orientation='Horizontal' Margin='2,2,2,0'> <TextBlock Text='Don't send when update was done by:' /> <StackPanel Orientation='Vertical' MaxHeight='275' MaxWidth='350' > <TextBlock x:Name='SelectedItemTextBlock' TextAlignment='Right' Width='200' Margin='5,0,5,0' /> <Grid x:Name='UserDropDownGrid' MaxHeight='75' MaxWidth='200' Visibility='Collapsed' ScrollViewer.VerticalScrollBarVisibility='Visible' ScrollViewer.HorizontalScrollBarVisibility='Hidden' > <Rectangle Fill='White' /> <Border Background='White'> <ListBox x:Name='UsersListBox' SelectionChanged='UsersListBox_SelectionChanged' ItemsSource='{Binding UserID}' /> </Border> </Grid> </StackPanel> <Button x:Name='DropDownButton' Click='DropDownButton_Click' VerticalAlignment='Top' Width='25' Height='25'> <Path Height='10' Width='10' Fill='#FF000000' Stretch='Fill' Stroke='#FF000000' Data='M514.66669,354 L542.16669,354 L527.74988,368.41684 z' HorizontalAlignment='Center' VerticalAlignment='Center' Margin='1,1,1,1'/> </Button> </StackPanel> </ContentControl> <TextBlock Text='Where Clause Condition:' /> <TextBox x:Name='WhereClauseTextBox' Height='200' Width='800' AcceptsReturn='True' TextWrapping='Wrap' /> <ContentControl> <StackPanel Orientation='Vertical'> <StackPanel Orientation='Horizontal'> <Button x:Name='TestConditionButton' Content='Test Condition' Margin='5,5,5,5' Click='TestConditionButton_Click' /> <Button x:Name='Save' Content='Save' HorizontalAlignment='Right' Margin='5,5,5,5' Click='Save_Click' /> <Button x:Name='Cancel' Content='Cancel' HorizontalAlignment='Right' Margin='5,5,5,5' Click='Cancel_Click' /> </StackPanel> <TextBlock x:Name='TestContitionResults' Visibility='Collapsed' /> </StackPanel> </ContentControl> </StackPanel> </Border> </Grid> </Grid>
And the call that occurs when the grid’s selection is changed:
Private Sub IncidentGrid_SelectionChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) If mFirstTime Then mFirstTime = False Else Dim data As SimpleASMX.EMailMonitor = CType(IncidentGrid.SelectedItem, SimpleASMX.EMailMonitor) Dim selectedGridItem As SimpleASMX.EMailMonitor = Nothing If IncidentGrid.SelectedItem IsNot Nothing Then selectedGridItem = CType(IncidentGrid.SelectedItem, SimpleASMX.EMailMonitor) EmailPopupTextBox.Text = selectedGridItem.Address SelectedItemTextBlock.Text = selectedGridItem.AppliesToUserID WhereClauseTextBox.Text = selectedGridItem.whereClause IncidentGrid.SelectedIndex = mEmailMonitorData.IndexOf(selectedGridItem) End If If IncidentGrid.SelectedIndex > -1 Then EditPersonPopupGrid.Visibility = Windows.Visibility.Visible Else EditPersonPopupGrid.Visibility = Windows.Visibility.Collapsed End If End If End Sub
Sorry if my code is atrocious, I’m still learning Silverlight.
That looks like a Silverlight bug to me. I’ve just tried it and what’s happening on my end is that the SelectionChanged event fires twice when you click the column header and to make matters worse, the index of the selected item doesn’t stay synched with the currently selected item.
I’d suggest you work your way around it by using the knowledge that the first time SelectionChanged fires, the value of the datagrid’s SelectedItem property will be null
Here’s some sample code that at least lives with the issue. Your SelectionChanged logic can go in the if clause.