【问题标题】:x:Bind converter with async methodx:使用异步方法绑定转换器
【发布时间】:2016-01-13 23:06:05
【问题描述】:

我在数据模板中有一个带有图像和一些文本块的 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?)。 我的问题是,是否有办法从文件中检索数据以用于图像控制以避免死锁?

【问题讨论】:

  • 我试图重现您的问题,但我不知道您的文件是什么样的。顺便说一句,为什么你不只是从文件中检索 url 并将它们直接添加到你的集合PlayerHistory

标签: c# uwp xbind


【解决方案1】:

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

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

这就是我的做法:您需要将 PlayerHistory 设为项目的 ObservableCollection,以便在添加新项目或从中删除旧项目时通知 ListView。根据您的代码 sn-p 我想您已经这样做了。您需要的第二件事是您必须使 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}" /> ...

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

【讨论】:

  • 避免转换器,有没有办法在绑定后迭代列表视图项?通过这种方式,我可以获取 url 列表并为每个项目设置 ImageSource。
  • 我做到了,谢谢。我仍在研究 MVVM,这些概念让我感到困惑:P
猜你喜欢
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-28
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 2015-07-01
相关资源
最近更新 更多