2014-07-14 135 views

回答

5

您可以利用的Binding

IsAsync财产MSDN

使用isAsync属性,当你绑定源的get访问 属性可能需要很长的时间。一个例子是一个图像属性,其中一个获取访问器的网页可从 下载。将IsAsync设置为true 可避免在发生下载时阻止UI。

例如

<Image Source="{Binding MyImage,IsAsync=True, Converter={StaticResource MyConverter}}" /> 

更多Binding.IsAsync


异步转换

我成功地创建一个异步转换器

namespace CSharpWPF 
{ 
    class AsyncConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      return new AsyncTask(() => 
      { 
       Thread.Sleep(4000); //long running job eg. download image. 
       return "success"; 
      }); 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 

     public class AsyncTask : INotifyPropertyChanged 
     { 
      public AsyncTask(Func<object> valueFunc) 
      { 
       AsyncValue = "loading async value"; //temp value for demo 
       LoadValue(valueFunc); 
      } 

      private async Task LoadValue(Func<object> valueFunc) 
      { 
       AsyncValue = await Task<object>.Run(()=> 
        { 
         return valueFunc(); 
        }); 
       if (PropertyChanged != null) 
        PropertyChanged(this, new PropertyChangedEventArgs("AsyncValue")); 
      } 

      public event PropertyChangedEventHandler PropertyChanged; 

      public object AsyncValue { get; set; } 
     } 
    } 
} 

该转换器将返回AsyncTask实例,它将封装长时间运行的作业中AsyncTask

类将异步执行任务,并将结果设置为AsyncValue,因为它也因此使用通知更新实现INotifyPropertyChanged UI

用法

<Grid xmlns:l="clr-namespace:CSharpWPF"> 
    <Grid.Resources> 
     <l:AsyncConverter x:Key="AsyncConverter" /> 
    </Grid.Resources> 
    <TextBlock DataContext="{Binding MyProperty,Converter={StaticResource AsyncConverter}}" 
       Text="{Binding AsyncValue}" /> 
</Grid> 

思想是将元件的DataContext结合到所述转换器和叔他所希望的属性,以

例如以上是使用文本块的文本属性,便于演示

〔实施例为IValueConverter相同的方法可以用于IMultiValueConverter太所作的新数据上下文的AsyncValue。

+1

这将只会异步调用MyImage getter,而不是转换器(这是OP要求的)。并且请标记来自其他资源的引文(例如*从MSDN *:'使用IsAsync属性...')。 – Clemens

+0

我明白了。作为解决方法,计算属性可用于执行长时间运行的功能而不是转换器。我试图找到一种方法来使用转换器异步。 – pushpraj

+1

可能的解决方法是另一个视图模型属性,您可以异步绑定*而不使用转换器。 – Clemens

0

首先,您应该提供一些示例代码,以便为答复者重现。

IsAsync不会帮助

使用IsAsync结合的,因为以下原因,将不利于:

  1. 我观察到,与IsAsync动态加载图像时,它会导致内存泄漏的时间。所以避免这种糖果IsAsync财产
  2. IsAsync不会总是帮助作为question here提到的一个问题情况下OP正试图从网络加载图像,但WPF是如此再解决在主线程上的DNS应用程序挂起而

的解决方案是使用连接绑定属性在WPF

详情:

  1. 你应该把索姆在XAML上SourceË缩略图图像
  2. 写一个附加属性的类加载在背景和更新图像源的图像中时,其可用(样品下面的代码相似种使用情况)
<Image my:ImageAsyncHelper.SourceUri="{Binding Author.IconUrl}" /> 

附加属性类

public class ImageAsyncHelper : DependencyObject 
{ 
    public static Uri GetSourceUri(DependencyObject obj) { return (Uri)obj.GetValue(SourceUriProperty); } 
    public static void SetSourceUri(DependencyObject obj, Uri value) { obj.SetValue(SourceUriProperty, value); } 
    public static readonly DependencyProperty SourceUriProperty = DependencyProperty.RegisterAttached("SourceUri", typeof(Uri), typeof(ImageAsyncHelper), new PropertyMetadata 
    { 
    PropertyChangedCallback = (obj, e) => 
    { 
     ((Image)obj).SetBinding(Image.SourceProperty, 
     new Binding("VerifiedUri") 
     { 
      Source = new ImageAsyncHelper { GivenUri = (Uri)e.NewValue }, 
      IsAsync = true, 
     }); 
    } 
    }); 

    Uri GivenUri; 
    public Uri VerifiedUri 
    { 
    get 
    { 
     try 
     { 
     Dns.GetHostEntry(GivenUri.DnsSafeHost); 
     return GivenUri; 
     } 
     catch(Exception) 
     { 
     return null; 
     } 

    } 
    } 
} 

如果你需要使用IMultiValueConverter与上述定义的附加属性,那么它应该像下面XAML代码:

附加属性与IMultiValueConverter

<Image> 
    <my:ImageAsyncHelper.SourceUri> 
     <MultiBinding Converter="{StaticResource MyImageMultiValueConverter}"> 
      <Binding Source="Author" Path="IconUrl"/> <!-- Binding Parameters --> 
      <Binding Path="ImageType"/> <!-- Binding Parameters --> 
      <Binding Path="MyParameterToConverter"/> <!-- Binding Parameters --> 
     </MultiBinding> 
    </my:ImageAsyncHelper.SourceUri> 
</Image> 

参考链接

  1. How can I keep a WPF Image from blocking if the ImageSource references an unreachable Url?
  2. Using multibinding to set custom attached property in WPF
+1

尽管警告不要使用它,但此解决方案似乎完全依赖于'IsAsync'(在新的Binding()'代码中)。 –