【发布时间】:2012-03-30 14:14:37
【问题描述】:
当进度发生变化时,我需要更新下载列表。
XAML:
<ListView ItemsSource="{Binding UiList}" x:Name="MyListView">
<ListView.View>
<GridView>
<GridViewColumn Header="Title"/>
<GridViewColumn Header="Progress"/>
</GridView>
</ListView.View>
</ListView>
创建Logic类实例并更新ListView内容的ViewModel:
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; }
}
逻辑:
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);
}
}
}
上面的代码不会更新 UI。我知道如何解决这个问题的两种方法:
在 xaml 代码隐藏调用中:
Application.Current.Dispatcher.Invoke(new Action(() => MyListView.Items.Refresh()));在 ViewModel 中将
List<>更改为ICollectionView并在列表更新后使用Application.Current.Dispatcher.Invoke(new Action(() => UiList.Refresh()));。
这两种方式都会导致问题:应该根据用户需求打开的 ListView 闪烁 和 Popup 总是在每次“刷新”后关闭:
<Popup Name="Menu" StaysOpen="False">
我可以用另一个控件或面板替换弹出窗口,但我需要它可能超出主窗口的边框(如屏幕上)。但我相信 WPF 有另一种方式来更新 ListView 的内容(不闪烁)。
PS:抱歉问了这么长的问题,但我不知道如何更简单地描述它......
【问题讨论】:
-
您应该将 List 更改为 ObservableCollection。
标签: wpf