C# 加快向列表框添加项目的速度(代码隐藏或xaml绑定?)
我在一个列表框中显示一个图像列表,每个图像下面都有一个标题。数据是一个JSON数组,数组中的每个子对象都有JObject listbox项是一个stackpanel,图像和文本被插入堆栈面板,然后作为一个项插入listbox 唯一的问题是它速度慢,数据量大(40个或更多项) 我听说XAML数据绑定要快得多,但是我不可能在屏幕上看到任何东西 XAML绑定是否会加快速度以使其可用?理想情况下,我希望它是即时的,或“弹出式”的风格,其中每个项目是添加,因为它是可用的,而不锁定程序。数据取自本地JSON文件和本地图像 如果在代码背后也能做到同样好,那就太好了。但我似乎无法提高速度。把它移到一个线程上也没有任何细微的差别 下面是我如何通过代码隐藏添加项目:C# 加快向列表框添加项目的速度(代码隐藏或xaml绑定?),c#,wpf,listbox,json.net,C#,Wpf,Listbox,Json.net,我在一个列表框中显示一个图像列表,每个图像下面都有一个标题。数据是一个JSON数组,数组中的每个子对象都有JObject listbox项是一个stackpanel,图像和文本被插入堆栈面板,然后作为一个项插入listbox 唯一的问题是它速度慢,数据量大(40个或更多项) 我听说XAML数据绑定要快得多,但是我不可能在屏幕上看到任何东西 XAML绑定是否会加快速度以使其可用?理想情况下,我希望它是即时的,或“弹出式”的风格,其中每个项目是添加,因为它是可用的,而不锁定程序。数据取自本地JSON
//在数据中循环
foreach(this.data.Select((value,i)=>new{i,value})中的动态项)
{
//创建此项目的图像
this.images[item.i]=新图像
{
宽度=278,
高度=178,
};
//如果此项目的图像存在
if(File.Exists(item.value[“Image”].ToString()))
{
//此图像的路径
字符串imageFilePath=item.value[“Image”].ToString();
//设置图像源
this.images[item.i].Source=new-BitmapImage(新Uri(imageFilePath,UriKind.RelativeOrAbsolute));
}
//创建一个堆栈面板来存储我们的项目
StackPanel StackPanel=新的StackPanel
{
宽度=288,
高度=215,
};
//创建项目文本
TextBlock TextBlock=新的TextBlock();
textBlock.text=item.value[“text”].ToString();
//将图像添加到堆栈面板
stackPanel.Children.Add(this.images[item.i]);
//将文本添加到堆栈面板
stackPanel.Children.Add(textBlock);
//将stackpanel添加到列表中
此.Items.Add(stackPanel);
}
窗口的XAML:
这是我试图绑定的列表框的XAML。它不会导致屏幕上出现任何内容
编辑:如果我将下面的代码移到一个方法中,并在代码中的某个地方调用该方法,它确实会导致我的图像/文本出现在屏幕上。它只是一开始不这么做,为什么?它也和代码隐藏版本一样慢
以及XAML绑定背后的代码
//用于存储数据的列表
私有列表testList{get;set;}
公共MyClass()
{
//初始化测试列表
this.testList=新列表();
//循环浏览数据
foreach(this.data.Select((value,i)=>new{i,value})中的动态项)
{
Item=Item.value.ToObject();
this.testList.Add(项);
}
this.ItemsSource=this.testList;
}
谢谢不要在代码隐藏中创建控件。相反,使用
列表框
和数据模板
的绑定
和项目模板
。我试图解释最佳方法:
创建具有以下两个属性的类:
public class Model : INotifyPropertyChanged
{
string _imageFilePath;
public string ImageFilePath { get { return _imageFilePath; } set { _imageFilePath = value; RaisePropertyChanged("ImageFilePath"); } }
string _text;
public string Text { get { return _text; } set { _text = value; RaisePropertyChanged("Text"); } }
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
}
}
您最重要的工作应该是通过循环数据来填充一个可观测集合
。让我们将此集合放入以下类中:
public class ViewModel
{
public ViewModel()
{
//populate the Models here
}
ObservableCollection<Model> _models;
public ObservableCollection<Model> Models { get { return _models; } set { _models = value; } }
}
这应该是可行的。不要在代码隐藏中创建控件。相反,使用
列表框
和数据模板
的绑定
和项目模板
。我试图解释最佳方法:
创建具有以下两个属性的类:
public class Model : INotifyPropertyChanged
{
string _imageFilePath;
public string ImageFilePath { get { return _imageFilePath; } set { _imageFilePath = value; RaisePropertyChanged("ImageFilePath"); } }
string _text;
public string Text { get { return _text; } set { _text = value; RaisePropertyChanged("Text"); } }
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
}
}
您最重要的工作应该是通过循环数据来填充一个可观测集合
。让我们将此集合放入以下类中:
public class ViewModel
{
public ViewModel()
{
//populate the Models here
}
ObservableCollection<Model> _models;
public ObservableCollection<Model> Models { get { return _models; } set { _models = value; } }
}
这应该行得通。ToObject在做什么?调用
ToObject
之前,值的类型是什么?ToObject是一个JSON.Net方法,可以在作业对象上调用该方法,将其转换为特定类型。在本例中是一个项,它是一个包含两个成员Image和text的类,ToObject
在做什么?调用ToObject
之前,值的类型是什么?ToObject是一个JSON.Net方法,可以在作业对象上调用该方法,将其转换为特定类型。在本例中是一个项,它是一个包含两个成员Image和text的类,您实际上不需要为列表框
指定数据上下文
。特别是因为DataContext={Binding}
只是将DataContext
绑定到自身。谢谢,我看到您的代码与我尝试的代码有些不同。我会做一个尝试,然后汇报我会接受它,因为它回答了我的问题,但我会问一个新的问题,这个问题更关注于我仍然有问题的一个特定方面。感谢您确实不需要为列表框
指定数据上下文
。特别是因为DataContext={Binding}
只是将DataContext
绑定到自身。谢谢,我看到您的代码与我尝试的代码有些不同。我会做一个尝试,然后汇报我会接受它,因为它回答了我的问题,但我会问一个新的问题,这个问题更关注于我仍然有问题的一个特定方面。谢谢