我有一个带有图像的ListView和一个带有datatamplate的TextBlocks。这些控件绑定来自集合对象的信息,但用于图像控制的URL位于文件上。我试图绑定一个字符串(这是文件的名称)并创建一个转换来检索该URL。
XAML:
<ListView Name="list" ItemsSource="{x:Bind Player.PlayerHistory, Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:HistoricoPartidas">
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Image Source="{x:Bind name, Converter={StaticResource ResourceKey=ItemConvert} }" />...
转换器:
class ItemConvert: IValueConverter {
public object Convert(object value, Type targetType, object parameter, string language) {
string s = value.ToString(); //value is binding from an object of a collection
ControlFile controle = new ControlFile();//class with file handler
Character ch = controle.get(s).Result;//return a Character from file "s"
return ch.Icon_URL;
}
我创建了上面的代码,但它导致了死锁(.Result?)。 我的问题是,是否有办法从文件中检索数据,在图像控制中使用避免死锁?
答案 0 :(得分:1)
如果您想坚持使用当前的解决方案(我强烈建议您反对),请阅读the accepted answer here,Cleary先生完整而深入地描述了这个问题。
我将如何做到这一点:你需要让PlayerHistory成为一个ObservableCollection项,这样ListView会在添加新项目或从中删除旧项目时收到通知。根据您的代码段,我想您已经这样做了。你需要做的第二件事是你必须在PlayerHistory中创建项目(现在让他们称之为HistoryViewModel)实现INotfyPropertyChanged interface,他们必须拥有一个属性(让&#39; s称之为PictureUri),它将绑定到DataTemplate中,并且必须在此属性的setter中引发PropertyChanged事件。 这些用代码编写:
class HistoryViewModel : INotifyPropertyChanged
{
private Uri _pictureUri;
public Uri PictureUri
{
get
{
return _pictureUri;
}
set
{
if (value == _pictureUri)
return;
_pictureUri = value;
RaisePropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
然后您的DataTemplate将如下所示:
<DataTemplate x:DataType="data:HistoryViewModel ">
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Image Source="{Binding PictureUri}" /> ...
这样,每当您更新支持ViewModels的PictureUri属性时,由于数据绑定,ListView的项目也会自动更新。