hmm, nie wiem, czy jest to "przyjemny" sposób, ale jeśli możesz uzyskać dostęp do wybranego elementu przed ponownym załadowaniem, możesz go zapisać (lub jego klucz lub coś) i ponownie wybrać programowo po zakończeniu ładowania.
szybkie makieta:
var selectedItem = myCombo.SelectedItem;
DoReload();
myCombo.SelectedItem = selectedItem;
Ale zakładam, że myśli w inny sposób niż ten ręcznej pracy wokół?
Nadzieja pomaga to w każdym razie ...
UPDATE
Ok widzę, z wątku tła.
Czy używasz ICollectionView do wiązania swojego combobox? Jeśli tak, możesz użyć właściwości CurrentItem, aby zachować referencję. Zrobiłem szybką makietę i to działa na mojej konfiguracji. to zakłada masz odniesienie do swojej Ui:
XAML
<Grid VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ComboBox ItemsSource="{Binding Items}" IsSynchronizedWithCurrentItem="True" Grid.Column="0" Grid.Row="0" DisplayMemberPath="Name"/>
<Button Command="{Binding UpdateCommand}" Grid.Column="1" Grid.Row="0">Update</Button>
</Grid>
View/ViewModel
public partial class Window1 : Window {
public Window1() {
InitializeComponent();
this.DataContext = new ViewModel(this);
}
}
public class ViewModel
{
private readonly Window1 window;
private ObservableCollection<Item> items;
private ICollectionView view;
public ViewModel(Window1 window) {
this.window = window;
items = new ObservableCollection<Item>
{
new Item("qwerty"),
new Item("hello"),
new Item("world"),
};
view = CollectionViewSource.GetDefaultView(items);
}
public ObservableCollection<Item> Items { get { return items; } }
public ICommand UpdateCommand {
get { return new RelayCommand(DoUpdate); }
}
public Item SelectedItem { get; set; }
private void DoUpdate(object obj) {
var act = new Func<List<Item>>(DoUpdateAsync);
act.BeginInvoke(CallBack, act);
}
private List<Item> DoUpdateAsync() {
return new List<Item> {
new Item("hello"),
new Item("world"),
new Item("qwerty"),
};
}
private void CallBack(IAsyncResult result) {
try {
var act = (Func<List<Item>>)result.AsyncState;
var list = act.EndInvoke(result);
window.Dispatcher.Invoke(new Action<List<Item>>(delegate(List<Item> lst) {
var current = lst.Single(i => i.Name == ((Item)view.CurrentItem).Name);
Items.Clear();
lst.ForEach(Items.Add);
view.MoveCurrentTo(current);
}), list);
} catch(Exception exc){ Debug.WriteLine(exc); }
}
}
public class Item {
public Item(string name) {
Name = name;
}
public string Name { get; set; }
}
Trzeba będzie zrobić jakąś manipulację w przypadku, gdy wybrana pozycja nie jest dłużej na liście.
Właściwość IsSynchronizedWithCurrentItem jest ważna tutaj, w przeciwnym razie nie będzie działać!
Sposób, w jaki tworzone jest odniesienie do głównego okna, powinien być również oparty na architekturze DI.
To może być rozwiązanie, chociaż nie jest tak ładne/łatwe, jak chciałbym: - | –
Prawdopodobnie nie trzeba aktualizować kolekcji z wątku tła. Pobierz bieżącą kolekcję z usługi sieciowej w tle, a następnie (zakładając, że korzystasz z usługi BackgroundWorker) zaktualizuj 'ObservableCollection' w zdarzeniu RunWorkerCompleted. –