x: привязать конвертер с помощью асинхронного метода

У меня есть ListView с изображением и некоторыми текстовыми блоками в таблице данных. Эти элементы управления связывают информацию из объекта коллекции, но 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?). Мой вопрос в том, есть ли способ получить данные из файла для использования в управлении изображениями, избегая тупиковой ситуации?


person vinicius    schedule 11.01.2016    source источник
comment
Я пытался воспроизвести вашу проблему, но не знаю, как выглядит ваш файл. Кстати, почему бы вам просто не получить URL-адреса из файла и не добавить их прямо в свою коллекцию PlayerHistory?   -  person panda    schedule 12.01.2016


Ответы (1)


панда прав, вам действительно не стоит открывать файл в конвертере. Таким образом, каждый раз, когда вызывается Convert (), вы будете открывать файл и читать из него, что без надобности отнимает слишком много времени и ресурсов. Не говоря уже о том, что это вешает ваш поток пользовательского интерфейса и вызывает тупик. Вы должны открыть файл до или во время заполнения вашего ListView, прочитать список URL-адресов из него и вместо этого привязаться к этой (наблюдаемой) коллекции.

Если вы хотите придерживаться своего текущего решения (чего я настоятельно не рекомендую), прочтите принятый ответ здесь, господин Клири прекрасно и подробно описывает проблему.

Вот как я бы это сделал: вам нужно сделать PlayerHistory ObservableCollection элементов, чтобы ListView получал уведомление, когда из него добавляются новые элементы или удаляются старые. Основываясь на вашем фрагменте кода, я полагаю, вы уже делаете это таким образом. Второе, что вам понадобится, это то, что вы должны сделать элементы в PlayerHistory (назовем их сейчас HistoryViewModel) реализацией INotfyPropertyChanged interface, они должны иметь свойство (назовем его 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}" /> ...

Таким образом, всякий раз, когда вы обновляете свойство PictureUri резервных ViewModels, элементы ListView также будут автоматически обновляться благодаря привязке данных.

person Péter Bozsó    schedule 13.01.2016
comment
Избегая конвертера, есть ли способ перебрать элементы списка после привязки? Таким образом я могу получить список URL-адресов и установить ImageSource для каждого элемента. - person vinicius; 13.01.2016
comment
Я сделал это и работал, спасибо. Я все еще изучаю MVVM, и эти концепции сбивают меня с толку: P - person vinicius; 13.01.2016