我有一段时间没有问题,我的Datagrid的Itemsource更新导致selectedItem被设置为null。我一直在谷歌搜索疯狂,最后有一些东西,所需的行保持选中,但我在行的第一个单元格周围得到一个黑盒子而不是整个行被突出显示。单击向上/向下箭头键将更改所选行,新行将按预期突出显示。
这是我的XAML:
<DataGrid ItemsSource="{Binding Path=FilteredSimResults}" ColumnWidth="*" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" IsReadOnly="True"
SelectedItem="{Binding Path=SelectedPdf}" SelectionMode="Single" SelectionUnit="FullRow" AlternatingRowBackground="LightGray"
Visibility="{Binding Path=IsNotPopulating}" Margin="5,0" Name="PdfList"
AutoGeneratingColumn="OnAutoGeneratingColumn">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsBold}" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.ItemContainerStyle>
<Style TargetType="DataGridRow">
<EventSetter Event="Selected" Handler="OnRowSelected"/>
</Style>
</DataGrid.ItemContainerStyle>
</DataGrid>
这是我背后的代码:
public SimulationGrid()
{
InitializeComponent();
CollectionView myCollectionView = (CollectionView)CollectionViewSource.GetDefaultView(PdfList.Items);
((INotifyCollectionChanged)myCollectionView).CollectionChanged += OnItemSourceChanged;
}
private void OnItemSourceChanged(object sender, EventArgs e)
{
if (_index == null) return;
object item = _index;
Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
{
PdfList.SelectedItem = item;
PdfList.ScrollIntoView(item);
DataGridRow row = (DataGridRow)PdfList.ItemContainerGenerator.ContainerFromItem(item);
row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}));
}
private void OnRowSelected(object sender, RoutedEventArgs e)
{
_index = ((DataGridRow)sender).Item;
}
编辑: 我绑定到这个:
public List<SimResult> FilteredSimResults
{
get
{
List<SimResult> filteredResults = new List<SimResult>();
if (!Populating && SimResults != null)
{
foreach (SimResult result in SimResults)
{
if ((string.IsNullOrEmpty(FilterKey) || result.PatientId.ToLower().Contains(FilterKey.ToLower()))
&& (ShowingHiddenSims != result.IsVisible))
{
filteredResults.Add(result);
}
}
}
return SimSortDirection == ListSortDirection.Descending
? filteredResults.OrderByDescending(o => o.GetType().GetProperty(SimSortColumn).GetValue(o)).ToList()
: filteredResults.OrderBy(o => o.GetType().GetProperty(SimSortColumn).GetValue(o)).ToList();
}
}
完整列表保存在内存中(SimResults),但它有几个可以修改列表,因此只有修改后的列表才会被发送到绑定。因此,每次修改时,都会修改完整列表。
答案 0 :(得分:0)
问题是每次更新都会完全取代您的物品清单。
当FilteredSimResults返回时,它每次返回一个完全不同的List对象,这不是处理这类事情的好方法。
如果你想更新ViewModel背后或代码中的数据(如果你使用MVVM),你应该使用ObservableCollection,这正是它所做的。
public ObservableCollection<SimResult> SimResults { get; set; } = new ObservableCollection<SimResult>();
绑定到XAML中的内容就像这样:
<DataGrid x:Name="dataGrid" HorizontalAlignment="Left" VerticalAlignment="Top" Height="319" Width="517" ItemsSource="{Binding SimResults}">
<DataGrid.Columns>
<DataGridTextColumn Header="PatientId" Binding="{Binding PatientId}"/>
</DataGrid.Columns>
</DataGrid>
一旦你有了ObservableCollection的任何更改将反映在网格中。需要注意的一点是,您的SimsResults类必须实现INotifyPropertyChanged事件。
您仍然会在删除时遇到此问题,或者如果您完全删除某个项目,但不应删除某个项目,只需更改其属性即可。