Мы наблюдаем странное поведение свойства SelectedItem
в нашем DataGrid
. Некоторая справочная информация:
DataGrid
отображает результат запроса к нашей базе данных. Есть кнопка, которая позволяет пользователю вручную обновить sh результаты в DataGrid
. Существует механизм автоматического обновления sh, благодаря которому результаты будут автоматически обновляться sh каждые 30 секунд.
Мы видим, что свойство SelectedItem
всегда становится индексом 0 ItemsSource для Datagrid когда происходит автоматическое обновление sh. Но мы хотим, чтобы текущая выбранная строка оставалась выбранной строкой после refre sh. Однако, если пользователь вручную нажимает refre sh, выбранная строка остается такой же после refre sh, что странно, потому что тот же код работает для refre sh logi c. И да, у нас есть код, который запоминает текущий выбранный элемент, который затем снова устанавливается после завершения sh refre.
Вот некоторые из соответствующих кодов:
<UserControl.Resources>
<CollectionViewSource Source="{Binding DataGridResults}" x:Key="ReferralItemsSource"/>
</UserControl.Resources>
<customControls:CustomDataGrid x:Name="GridControl"
ItemsSource="{Binding Source={StaticResource ReferralItemsSource}}"
SelectedItem="{Binding DataContext.SelectedReferral, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
IsReadOnly="False"
IsSynchronizedWithCurrentItem="True"
SelectionMode="Single">
private async void RefreshWorklist(bool invokedByAutoRefresh = false)
{
try
{
if (Initialising || ShowSpinner || IsProcessing || ShowRefreshSpinner || IsCurrentWorklistDeleted || !_sessionData.IsActive()) return;
IsProcessing = true;
RefreshWorklistCommand.RaiseCanExecuteChanged();
if (CurrentWorklistId != null)
{
var selectedReferralId = SelectedReferral.pk_Referral_ID;
if (invokedByAutoRefresh)
{
// Refresh has been invoked by _timer, so show spinner on the results page only
ShowRefreshSpinner = true;
}
else
{
// User has manually clicked refresh button so show app wide spinner
ShowSpinner = true;
if (_timer != null)
{
SetupWorklistRefreshTimer(); // Setup _timer again so that it will refresh again at an appropriate time
}
}
Referrals = await _referralRepository.GetReferralsFromWorklistAsync(CurrentWorklistId.Value, invokedByAutoRefresh);
if (Filters.Count > 0)
{
var listOfReferralPks = ReferralFiltering.GetFilteredResults(Referrals, Filters.Where(f => f.HasBeenApplied).ToList());
var filteredResults = Referrals.Where(r => listOfReferralPks.Contains(r.pk_Referral_ID)).ToList();
DataGridResults = MapReferralLookupItemsToReferralLookupItemViewModels(filteredResults);
}
else
{
DataGridResults = MapReferralLookupItemsToReferralLookupItemViewModels(Referrals);
}
SelectedReferral = DataGridResults.FirstOrDefault(r => r.pk_Referral_ID == selectedReferralId);
}
}
catch (Exception e)
{
_errorHandler.DisplayError(e);
}
}
Как объяснялось ранее, RefreshWorklist()
вызывается вручную refre sh через Command
:
private void Execute_RefreshWorklist()
{
RefreshWorklist();
}
Или автоматически с помощью Timer
:
private void SetupWorklistRefreshTimer()
{
_timer?.Dispose();
var refreshInterval = _userSettingsRepository.GetIntegerSystemSetting("ReferralsWorklistRefreshInterval");
if (refreshInterval <= 0) return; // If this is 0 or below then the refresh should be disabled
if (refreshInterval < 10) // If it is less than 10 then set it to 10 to avoid too many MT calls
{
refreshInterval = 10;
}
var timeUntilFirstTick = refreshInterval * 1000;
_timer = new Timer((s) => RefreshWorklist(true), null, timeUntilFirstTick, refreshInterval * 1000);
}
И, наконец, свойство привязки модели представления свойств SelectedItem
:
public ReferralLookupItemViewModel SelectedReferral
{
get { return _selectedReferral; }
set
{
if (_selectedReferral != value)
{
_selectedReferral = value;
OnPropertyChanged();
}
}
}
Кто-нибудь знает, почему происходит такое поведение? Это как-то связано с Timer
? Я понимаю, что это непростой вопрос, поэтому, пожалуйста, обращайтесь за дополнительной информацией.