2014-07-14 40 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()'代碼中)。 –