Silverlight- DataGrid 控件 - 选择更改事件干扰排序
Posted
技术标签:
【中文标题】Silverlight- DataGrid 控件 - 选择更改事件干扰排序【英文标题】:Silverlight- DataGrid control - Selection Changed event interfering with sorting 【发布时间】:2010-09-09 14:55:59 【问题描述】:我目前正在使用 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。
【问题讨论】:
【参考方案1】:在我看来,这就像一个 Silverlight 错误。我刚刚尝试过,最终发生的情况是,当您单击列标题时 SelectionChanged 事件会触发两次,更糟糕的是,所选项目的索引不会与当前选中的项目。
我建议您通过使用第一次触发 SelectionChanged 时数据网格的 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;
【讨论】:
【参考方案2】:Silverlight DataGrid 中的冻结列..
http://dotnetdreamer.wordpress.com/2009/01/31/silverlight-2-datagrid-frozen-columns/
【讨论】:
【参考方案3】:您提到的第一个问题有一个错误修复(选择更改事件在度假时被触发)。
微软的补丁见以下网址:
http://www.microsoft.com/downloads/details.aspx?familyid=084A1BB2-0078-4009-94EE-E659C6409DB0&displaylang=en
【讨论】:
【参考方案4】:这行得通,但现在如果我排序两次,第一次排序,然后弹出作为 grid 的第一个选定项目。如果我关闭弹出网格,然后再次尝试排序,它会堆栈溢出,并使 firefox 崩溃。
我想我可能需要重新考虑在 Silverlight 中工作,直到系统变得更加稳定为止。
感谢霍维托的回答!
【讨论】:
以上是关于Silverlight- DataGrid 控件 - 选择更改事件干扰排序的主要内容,如果未能解决你的问题,请参考以下文章
Silverlight:如何访问 DataGrid RowDetailTemplate 中的控件
Silverlight 2 DataGrid December 2008
Silverlight Combobox 将所选项目设置为 datagrid 的所选项目