Сохранять тот же выбранный элемент в ListView, когда коллекция, с которой он связан, обновляется - PullRequest
1 голос
/ 28 января 2010

У меня есть ListView, который связан с ObservableCollection, который сам является производным от IQueryable. Когда я обновляю коллекцию, после добавления элементов, редактирования или нажатия кнопки (чтобы увидеть, есть ли в базе данных новые элементы от других пользователей). Список обновляется и выбирает первый элемент в коллекции.

Я хочу сохранить тот же выбранный элемент (если он все еще существует) после обновления, но поскольку коллекция была заменена, я не могу сравнить равенство между элементом в старой коллекции и новым. Все попытки никогда не совпадают.

Как это сделать?

Ниже приведены некоторые соответствующие фрагменты кода, если кто-то хочет их увидеть:

Событие 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>

Коллекция Issues обновляется с помощью метода QueryIssues, который строит запрос 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 ]

1 голос
/ 29 января 2010

Поскольку вы получаете совершенно новые объекты, нет другого способа сопоставить равенство, кроме как найти предмет, который соответствует старому (если он существует), и выбрать его. Вы заменяете свою коллекцию, что означает, что вы должны отслеживать выбранный элемент самостоятельно.

Другие опции:

Вы можете сохранить коллекцию и вручную добавить / удалить элементы на основе результатов запроса (т.е. не уничтожать текущий элемент).

1 голос
/ 06 июля 2010

Один из способов сделать это в модели просмотра:

// 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);
0 голосов
/ 28 января 2010

Когда я сталкивался с этой проблемой в прошлом, я обернул элементы, которые я хочу отобразить, в небольшой класс модели представления, затем дал каждому дополнительное свойство IsSelected и затем связал это свойство с ListBoxItem, используя ItemContainerStyle. Таким образом, я отслеживаю то, что выбрано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...