Ich muss die Liste der Downloads aktualisieren, wenn der Fortschritt geändert wurde.So aktualisieren Sie ListView, wenn vorhandene Elemente der gebundenen Liste aktualisiert wurden
XAML:
<ListView ItemsSource="{Binding UiList}" x:Name="MyListView">
<ListView.View>
<GridView>
<GridViewColumn Header="Title"/>
<GridViewColumn Header="Progress"/>
</GridView>
</ListView.View>
</ListView>
Ansichtsmodell, das eine Instanz der Logik-Klasse erstellt und aktualisiert den Inhalt der Listview:
class MainWindowViewModel : ViewModelBase
{
private readonly Logic _logic;
public List<Model> UiList { get; set; }
public MainWindowViewModel()
{
_logic = new Logic();
_logic.Update += LogicUpdate;
Start = new RelayCommand(() =>
{
var worker = new BackgroundWorker();
worker.DoWork += (sender, args) => _logic.Start();
worker.RunWorkerAsync();
});
}
void LogicUpdate(object sender, EventArgs e)
{
UiList = _logic.List;
RaisePropertyChanged("UiList");
}
public ICommand Start { get; set; }
}
Logic:
public class Logic
{
readonly List<Model> _list = new List<Model>();
public event EventHandler Update;
public List<Model> List
{
get { return _list; }
}
public void Start()
{
for (int i = 0; i < 100; i++)
{
_list.Clear();
_list.Add(new Model{Progress = i, Title = "title1"});
_list.Add(new Model { Progress = i, Title = "title2" });
var time = DateTime.Now.AddSeconds(2);
while (time > DateTime.Now)
{ }
Update(this, EventArgs.Empty);
}
}
}
Der obige Code würde nicht aktualisieren Benutzeroberfläche. Ich kenne zwei Art und Weise, wie dieses Problem zu beheben:
in XAML Code-Behind-Aufruf:
Application.Current.Dispatcher.Invoke(new Action(() => MyListView.Items.Refresh()));
In Ansichtsmodell ändern
List<>
-ICollectionView
und verwendenApplication.Current.Dispatcher.Invoke(new Action(() => UiList.Refresh()));
, nachdem die Liste aktualisiert wurde.
Beide Wege führen das Problem: das Listview blinkt und Popup, die immer auf die Nachfrage der Nutzer offen sein sollte schließt nach jedem "refresh":
<Popup Name="Menu" StaysOpen="False">
Ich kann das Popup durch ein anderes Steuerelement oder Panel ersetzen, aber ich brauche seine Möglichkeit, außerhalb des Hauptfensters zu sein (wie auf dem Bildschirm). Aber ich glaube, dass WPF eine andere Möglichkeit bietet, den Inhalt von ListView zu aktualisieren (ohne zu blinken).
PS: Sorry für die lange Frage, aber ich weiß nicht, wie es kurz zu beschreiben ...
Sie sollten die Liste in ObservableCollection ändern. – Silvermind