Silverlight-DataGrid控件-选择更改的事件干扰了排序
我目前正在使用Silverlight(Beta 2)Datagrid控件。在连接SelectionChanged事件之前,通过单击标题可以对网格进行完美排序。现在,当单击网格时,当我单击标题进行排序时,它将触发SelectionChanged事件。有没有办法解决?
在一个半相关的主题中,我想在单击一个已选择的项目时触发SelectionChanged事件(这样我就可以弹出一个窗口来允许用户编辑所选择的值)。现在,我们必须单击不同的值,然后返回到所需的值才能弹出它。还有另一种方法吗?
包括我的代码。
这一页:
<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>
以及更改网格的选择时发生的调用:
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
抱歉,如果我的代码很糟糕,我仍在学习Silverlight。
解决方案
回答
在我看来,这似乎是Silverlight的错误。我刚刚尝试过,最后发生的是,当我们单击列标题时,SelectionChanged事件将触发两次,更糟糕的是,所选项目的索引不会与当前所选项目保持同步。
我建议我们使用以下知识来解决该问题,即首次启动SelectionChanged时,datagrid的SelectedItem属性的值将为null
这是至少与该问题有关的一些示例代码。SelectionChanged逻辑可以放在if子句中。
public partial class Page : UserControl { private Person _currentSelectedPerson; public Page() { InitializeComponent(); List<Person> persons = new List<Person>(); persons.Add(new Person() { Age = 5, Name = "Tom" }); persons.Add(new Person() { Age = 3, Name = "Lisa" }); persons.Add(new Person() { Age = 4, Name = "Sam" }); dg.ItemsSource = persons; } private void SelectionChanged(object sender, EventArgs e) { DataGrid grid = sender as DataGrid; if (grid.SelectedItem != null) { _currentSelectedPerson = grid.SelectedItem as Person; } else { grid.SelectedItem = _currentSelectedPerson; } } } public class Person { public string Name { get; set; } public int Age { get; set; } }
回答
这可行,但是现在如果我进行两次排序,则在第一个列表上进行排序,然后将弹出窗口作为网格的第一个选定项。如果我关闭弹出网格,然后尝试第二次排序,则它会溢出并导致Firefox崩溃。
我想我可能需要重新考虑在Silverlight中工作,直到系统变得更加稳定为止。
感谢答案霍维托!
回答
Silverlight DataGrid中的冻结列
http://dotnetdreamer.wordpress.com/2009/01/31/silverlight-2-datagrid-frozen-columns/
回答
我们提到的第一个问题有一个错误修正(选择更改事件在度假村触发)。
请参阅以下URL以获取Microsoft的补丁程序:
http://www.microsoft.com/downloads/details.aspx?familyid=084A1BB2-0078-4009-94EE-E659C6409DB0&displaylang=en