我在列表框中显示图像列表,每个图像下面都有一个标题。数据是一个JSON数组,其中包含数组中每个子节点的JObject。
列表框项目是一个堆栈面板,图像和文本将插入到堆栈面板中,然后将其作为项目插入到列表框中。
唯一的问题是它有很多数据(40个或更多项)很慢。
我听说XAML数据绑定速度要快得多,但屏幕上没有任何运气。
XAML绑定会加快速度吗?它可以使用吗?理想情况下,我希望它是即时的,或者#34; pop in"每个项目在可用时添加的样式,而不会锁定程序。数据来自本地JSON文件和本地映像。
如果它可以在后面的代码中做得很好,那么很棒。但我似乎无法提高速度。把它移到一个线程也没有任何边际差异。
以下是我通过后面的代码添加项目的方法:
// Loop through the data
foreach (dynamic item in this.data.Select((value, i) => new { i, value }))
{
// Create the image for this item
this.images[item.i] = new Image
{
Width = 278,
Height = 178,
};
// If the image for this item exists
if (File.Exists(item.value["Image"].ToString()))
{
// The path to this image
string imageFilePath = item.value["Image"].ToString();
// Set the image source
this.images[item.i].Source = new BitmapImage(new Uri(imageFilePath, UriKind.RelativeOrAbsolute));
}
// Create a stack panel to store our item
StackPanel stackPanel = new StackPanel
{
Width = 288,
Height = 215,
};
// Create the items text
TextBlock textBlock = new TextBlock();
textBlock.text = item.value["Text"].ToString();
// Add the Image to the stack panel
stackPanel.Children.Add(this.images[item.i]);
// Add the text to the stack panel
stackPanel.Children.Add(textBlock);
// Add the stackpanel to the list
this.Items.Add(stackPanel);
}
The Window的XAML:
<Window x:Class="MyProject.Windows.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyProject"
mc:Ignorable="d"
Title="Window" Width="800" Height="600">
<Grid>
<!-- The list box -->
<ListBox x:Name="listBox" />
</Grid>
</Window>
这是我尝试绑定的ListBox的XAML。它导致屏幕上没有任何内容。
编辑:如果我将下面的代码移到一个方法中,并在我的代码中的某处调用该方法,它会导致我的图像/文本出现在屏幕上。它最初没有做到,为什么?它也和版本背后的代码一样慢。
<ListBox x:Name="listBox" ItemsSource="{Binding testList}">
<ListBox.ItemTemplate>
<DataTemplate>
<VirtualizingStackPanel>
<Image Source="{Binding Image}"/>
<TextBlock Text="{Binding Text}" FontSize="20" />
</VirtualizingStackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
XAML绑定背后的代码
// List to store our data
private List<Item> testList { get; set; }
public MyClass()
{
// Initialise the test list
this.testList = new List<Item>();
// Loop through the data
foreach (dynamic item in this.data.Select((value, i) => new { i, value }))
{
Item item = item.value.ToObject<Item>();
this.testList.Add(item);
}
this.ItemsSource = this.testList;
}
谢谢
答案 0 :(得分:3)
不要在代码背后创建控件。相反,请使用Binding
和ItemTemplate
的{{1}}和ListBox
。我试着解释最好的方法:
使用以下两个属性创建一个类:
DataTemplate
您最重要的工作应该是通过循环浏览数据来填充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));
}
}
。让我们把这个集合放在下面的类中:
ObservableCollection<Model>
使用
public class ViewModel
{
public ViewModel()
{
//populate the Models here
}
ObservableCollection<Model> _models;
public ObservableCollection<Model> Models { get { return _models; } set { _models = value; } }
}
为DataContext设置属性:
<ListBox ItemsSource="{Binding Models}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding ImageFilePath }"/>
<TextBlock Text="{Binding Text}" FontSize="20" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
这应该有用。