在刷新绑定的集合时,在ListView中保留相同的选定项

时间:2010-01-28 07:15:56

标签: c# wpf linq-to-sql data-binding listview

我有一个绑定到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);
}

3 个答案:

答案 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。这样我就可以跟踪所选内容。