wpf画面ListBox绑定的数据发生变化时 画面闪烁

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wpf画面ListBox绑定的数据发生变化时 画面闪烁相关的知识,希望对你有一定的参考价值。

ListBox的ItemsSource属性绑定了一个ObservableCollection集合,在画面隐藏时对集合进行添加项或删除项操作后,再显示画面时ListBox会从操作前的状态闪烁到操作后的状态。
这个是否因为虽然绑定数据已经变化但画面必须在显示时才能刷新。能不能在后台刷新让画面显示时没有闪烁的过程
只能发一部分代码,希望有帮助
集合数据绑定:
<ListBox Name="lstbox" ScrollViewer.VerticalScrollBarVisibility="Auto" ItemsSource="Binding mylist" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Background="Transparent" BorderThickness="0">
图片绑定:
<ImageBrush ImageSource="Binding ResourceUri, Converter=StaticResource uriToImageConv"/>
注:uriToImageConv中的转换代码
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(value.ToString());
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.EndInit();
return bi;
数据量不大,集合中只有2个元素时移除其中一个也会闪烁,每个元素中有一个图片地址的属性绑定到画面的ImageBrush控件上显示用,这个地址是经过BitmapImage转换后绑定的,不知道是否和这个有关系

ObervableCollection集合是响应修改的,当集合修改时,会触发ObervableCollection集合对形象的PropertyChanged事件,绑定后WPF会自动响应事件,并对界面做出调整。
按道理讲,你修改集合之后,ListBox中的各个Node是各自刷新显示的,也就是你改了那个刷新哪个,你的问题估计是处在是否是在修改后调用了最高Node的OnPropertyChanged方法或者绑定重新执行了一遍,还有可能是ListBox控件重新载入,重新初始化造成的。
你没有具体说,我也不能确定。
至于刷新方法那是没有。

总结一下:
1.最高Node的OnPropertyChanged方法
2.绑定重新执行了一遍
3.ListBox控件重新载入
以上三中情况会造成那种效果,你排查一下吧。追问

好,先感谢两位的答案,我先按这些检查一下,希望各位继续提出好主意,呵呵

参考技术A 你的数据量很大吗?否则不会看到这个过程的,又或者你的方式不对,能看看代码吗?

WPF绑定之索引器值变化通知

背景

在某些应用中,需要在界面上绑定到索引器,并在值发生变化时实时更新。

解决方案

只要将包含索引器的类实现INotifyPropertyChanged接口,并在索引值更改时引发PropertyChanged事件,并将属性名称设置为Item[]即可。示例代码如下:

public class NotifyDictionary : INotifyPropertyChanged
{
    private readonly Dictionary<string, string> _dictionary = new Dictionary<string, string>();
    
    public string this[string index]
    {
        get
        {
            if (_dictionary.ContainsKey(index))
            {
                return _dictionary[index];
            }

            return string.Empty;
        }
        set
        {
            string oldValue = string.Empty;
            if (_dictionary.ContainsKey(index))
            {
                oldValue = _dictionary[index];
            }

            _dictionary[index] = value;

            if (oldValue != value)
            {
                OnPropertyChanged(Binding.IndexerName);
            }
        }
    }
    
    #region INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion INotifyPropertyChanged

}

在 代码中,Binding.IndexerName是一个常量,值即为Item[]。

原理

本质上,索引器也是属性,即有参属性。

在WPF的绑定系统中,会监听属性更改事件,如果变化的属性名称为Item[]而且绑定的是索引器,则会更新界面值。可以看出,这个过程与索引器实际名称无关系。所以,即使是在索引器上使用IndexerNameAttribute显式更改索引器名称也不影响整个过程。

无参属性绑定冷知识

在WPF绑定系统中,会监听属性更改事件。但是如果绑定的属性为无参属性(即正常属性,非索引器),其与变化的属性名称比较是不区分大小写的。所以在下面的代码中

private string _name;

public string Name
{
    get { return this._name; }
    set
    {
        if (_name != value)
        {
            _name = value;
            this.OnPropertyChanged("naMe");
        }
    }
}

name、Name、naMe、naME效果是一样的。

代码下载

博客园:NotifyDictionaryDemo

以上是关于wpf画面ListBox绑定的数据发生变化时 画面闪烁的主要内容,如果未能解决你的问题,请参考以下文章

WPF 数据绑定问题!!求解求解

WPF ListBox 未使用 ItemsSource 更新

C#Aforge检测画面变化自动拍照

WPF ListBox 模板绑定仅在滚动时更新

wpf listbox 绑定

WPF如何更改xaml代码里ListBox的数据绑定