我有一个绑定到ObservableCollection的ListView,它本身是从IQueryable派生的。刷新集合后,在添加,编辑项目或单击按钮后(查看数据库是否包含来自其他用户的新项目)。列表框刷新并选择集合中的第一个项目。
我希望在刷新后保留相同的选定项目(如果它仍然存在),但因为已经替换了Collection,我似乎无法比较旧集合中的项目与新项目之间的相等性。所有attemtps都没有匹配。
应该怎么做?
如果有人想看到它们,下面是一些相关的代码snipets:
ListView,MouseDoubleClick事件打开一个编辑窗口
<ListView x:Name="IssueListView"
ItemsSource="{Binding Issues}"
ItemTemplate="{StaticResource ShowIssueDetail}"
IsSynchronizedWithCurrentItem="True"
MouseDoubleClick="IssueListView_MouseDoubleClick" />
这是DataTemplate
<DataTemplate x:Key="ShowIssueDetail">
<Border CornerRadius="3" Margin="2" MinWidth="400" BorderThickness="2"
BorderBrush="{Binding Path=IssUrgency,
Converter={StaticResource IntToRYGBBorderBrushConverter}}">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=IssSubject}"
Margin="3" FontWeight="Bold" FontSize="14"/>
<!--DataTrigger will collapse following panel for simple view-->
<StackPanel Name="IssueDetailPanel" Visibility="Visible" Margin="3">
<StackPanel Width="Auto" Orientation="Horizontal">
<TextBlock Text="Due: " FontWeight="Bold"/>
<TextBlock Text="{Binding Path=IssDueDate, StringFormat='d'}"
FontStyle="Italic" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel Width="Auto" Orientation="Horizontal">
<TextBlock Text="Category: " FontWeight="Bold"/>
<TextBlock Text="{Binding Path=IssCategory}"/>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=StatusBoardViewModel.ShowDetailListItems,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}}" Value="False">
<Setter TargetName="IssueDetailPanel"
Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
通过执行QueryIssues方法刷新Issues集合,该方法基于绑定控件以编程方式构建Linq To SQL查询。 IssuesQuery是一个IQueryable属性
public void QueryIssues()
{
// Will show all items
IssuesQuery = from i in db.Issues
orderby i.IssDueDate, i.IssUrgency
select i;
// Filters out closed issues if they are not to be shown
if (includeClosedIssues == false)
{
IssuesQuery = from i in IssuesQuery
where i.IssIsClosed == false
select i;
}
// Filters out Regular Tasks if they are not to be shown
if (showTasks == false)
{
IssuesQuery = from i in IssuesQuery
where i.IssIsOnStatusBoard == true
select i;
}
// Filters out private items if they are not to be shown
if (showPrivateIssues == false)
{
IssuesQuery = from i in IssuesQuery
where i.IssIsPrivate == false
select i;
}
// Filters out Deaprtments if one is selected
if (departmentToShow != "All")
{
IssuesQuery = from i in IssuesQuery
where i.IssDepartment == departmentToShow
select i;
}
Issues = new ObservableCollection<Issue>(IssuesQuery);
}
答案 0 :(得分:1)
因为您获得了全新的对象,所以没有其他方法可以匹配相等而不是找到与旧项目匹配的项目(如果存在)并选择它。您正在替换您的收藏,这意味着您必须自己跟踪所选项目。
其他选择:
您可以保留一个集合并根据查询结果手动添加/删除项目(即不要销毁当前项目)。
答案 1 :(得分:1)
在视图模型中执行此操作的一种方法:
// The ListView's SelectedItem is bound to CurrentlySelectedItem
var selectedItem = this.CurrentlySelectedItem;
// ListView is bound to the Collection property
// setting Collection automatically raises an INotifyPropertyChanged notification
this.Collection = GetIssues(); // load collection with new data
this.CurrentlySelectedItem = this.Collection.SingleOrDefault<Issue>(x => x.Id == selectedItem.Id);
答案 2 :(得分:0)
在过去遇到这个问题时,我已经将要显示的项目包装在一个小视图模型类中,然后为每个项目提供一个额外的属性IsSelected,然后使用ItemContainerStyle将此属性绑定到ListBoxItem。这样我就可以跟踪所选内容。