Я реализую ComboBox, который может быть обновлен пользователями с помощью кнопки. Я пытаюсь сделать так, чтобы ранее выбранный элемент автоматически переизбирался, если он все еще присутствует внутри ComboBox после обновления.WPF - Восстановить Предыдущий SelectedItem, когда ComboBox Изменения ItemSource
MainWindow.xaml:
<ComboBox Canvas.Left="10" Canvas.Top="10" DisplayMemberPath="Name" IsEnabled="{Binding Path=Enabled}" ItemsSource="{Binding Path=Items}" SelectedItem="{Binding Mode=TwoWay, Path=SelectedItem}" Width="379"/>
<Button Content="{x:Static p:Resources.TextRefresh}" Canvas.Right="10" Canvas.Top="10" Click="OnClickButtonRefresh" Width="75"/>
MainWindow.xaml.cs:
public MainWindow()
{
InitializeComponent();
DataContext = m_BrowserInstances = new BrowserInstancesViewModel();
}
private void OnClickButtonRefresh(Object sender, RoutedEventArgs e)
{
m_BrowserInstances.Populate();
}
[отредактирован CURRENT VERSION] BrowserInstancesViewModel.cs:
public sealed class BrowserInstancesViewModel : ViewModel
{
private Boolean m_Enabled;
public Boolean Enabled
{
get { return m_Enabled; }
}
private BrowserInstance m_SelectedItem;
public BrowserInstance SelectedItem
{
get { return m_SelectedItem; }
set
{
if (m_SelectedItem != value)
{
m_SelectedItem = value;
NotifyPropertyChanged("SelectedItem");
}
}
}
private ObservableCollection<BrowserInstance> m_Items;
public ObservableCollection<BrowserInstance> Items
{
get { return m_Items; }
}
public BrowserInstancesViewModel()
{
Populate();
}
private static Func<BrowserInstance, Boolean> Recover(BrowserInstance selectedItem)
{
return x =>
{
Process currentProcess = x.Process;
Process selectedProcess = selectedItem.Process;
if (currentProcess.Id != selectedProcess.Id)
return false;
if (currentProcess.MainModule.BaseAddress != selectedProcess.MainModule.BaseAddress)
return false;
if (currentProcess.MainWindowTitle != selectedProcess.MainWindowTitle)
return false;
return true;
};
}
public void Populate()
{
BrowserInstance item = m_SelectedItem;
List<BrowserInstance> items = new List<BrowserInstance>();
foreach (Process process in Process.GetProcessesByName("chrome"))
items.Add(new BrowserInstance(process));
if (items.Count > 0)
{
m_Enabled = true;
m_Items = new ObservableCollection<BrowserInstance>(items.OrderBy(x => x.Process.Id));
if (item != null)
m_SelectedItem = m_Items.SingleOrDefault(Recover(item));
if (m_SelectedItem == null)
m_SelectedItem = m_Items[0];
}
else
{
m_Enabled = false;
m_Items = new ObservableCollection<BrowserInstance>();
m_Items.Add(new BrowserInstance());
m_SelectedItem = m_Items[0];
}
NotifyPropertyChanged("Enabled");
NotifyPropertyChanged("Items");
NotifyPropertyChanged("SelectedItem");
}
}
я могу получить назад ранее выбранный элемент, но только иногда. Похоже, что код не работает должным образом, когда мне нужно выбрать значение по умолчанию (индекс 0), если предыдущий выбранный элемент не может быть восстановлен.
Вау спасибо! Каков наилучший способ реализации членов равенства в пользовательском классе? Мой класс BrowserInstance имеет только два поля: 'System.Diagnostics.Process' Process и' System.String Name' ... все, что мне нужно, чтобы сравнить процессы, но я не могу найти способ правильно проверить, если два процессы идентичны. –
@ Zarathos: вам нужно будет переопределить 'Object.Equals' и' Object.GetHashCode'. Как именно вы выполняете сравнение, зависит от вас и вашей программы. Это зависит от того, как вы определяете равенство для BrowserInstance. Например, вы можете использовать логику из 'Recover'. –
Mhhhh ... Я тестирую свой код, и я все еще вижу некоторые проблемы. Если я продолжаю нажимать кнопку Refresh, по неизвестной причине выбранный элемент ComboBox мигает (иногда он пуст, иногда нет). Я не могу понять причину. Я отредактировал вопрос с моим отредактированным кодом, следуя вашим предложениям. –