0

我在数据模板中有一个带有图像和一些文本块的 ListView。这些控件绑定来自集合对象的信息,但图像控件的 url 在文件上。我试图绑定一个字符串(这是文件的名称)并创建了一个转换来检索 url。

xml:

<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?)。我的问题是是否有办法从文件中检索数据以用于图像控制以避免死锁?

4

1 回答 1

1

熊猫是对的,你真的不应该在转换器中打开文件。这样,每次调用 Convert() 时,您都会打开文件并从中读取,这会不必要地占用太多时间和资源。更不用说它会挂起你的 UI 线程并导致死锁。您应该在填充 ListView 之前或期间打开文件,从中读取 URL 列表并改为绑定到该(可观察的)集合。

如果您想坚持当前的解决方案(我强烈建议您不要这样做),请在此处阅读已接受的答案,Cleary 先生完美而深入地描述了该问题。

我就是这样做的:您需要将 PlayerHistory 设置为项目的 ObservableCollection,以便在添加新项目或从中删除旧项目时通知 ListView。根据您的代码片段,我想您已经这样做了。您需要的第二件事是您必须使 PlayerHistory 中的项目(我们现在称它们为 HistoryViewModel)实现INotfyPropertyChanged 接口,它们必须有一个属性(我们称它为 PictureUri),您将绑定到您的DataTemplate,他们必须在此属性的设置器中引发 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}" /> ...

这样,每当您更新支持 ViewModel 的 PictureUri 属性时,ListView 的项目也会自动更新,这要归功于数据绑定。

于 2016-01-13T13:01:17.020 回答