2017-10-05 256 views
-2

我在我的视图中有一个WPF图像控件。当图像被加载时,我想要触发一个在我的模型视图中定义和执行的事件。我怎样才能做到这一点?我不知道如何使用命令执行此操作。MVVM WPF Fire图像加载完成后的命令(加载事件)

<Image Grid.Row="0" 
     Source="{Binding Path=ImageSrc, NotifyOnTargetUpdated=True, Converter={StaticResource imgToSrcConverter}}" 
     Visibility="{Binding ImgVisibility}" 
     RenderTransformOrigin="0,0" 
     SnapsToDevicePixels="True" 
     OverridesDefaultStyle="False" 
     TargetUpdated="targetUpdated" 
     Cursor="Hand" 
     RenderOptions.BitmapScalingMode="LowQuality" 
     RenderOptions.EdgeMode="Aliased"> 
<Image.Effect> 
     <DropShadowEffect Opacity="0.8" BlurRadius="8">     
     </DropShadowEffect> 
    </Image.Effect> 
</Image> 

转换

public class ImgToSrcConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, 
      System.Globalization.CultureInfo culture) 
    { 
     Image image = value as Image; 
     if (image != null) 
     { 
      MemoryStream ms = new MemoryStream(); 
      image.Save(ms, image.RawFormat); 
      ms.Seek(0, SeekOrigin.Begin); 
      BitmapImage bi = new BitmapImage(); 
      bi.BeginInit(); 
      bi.StreamSource = ms; 
      bi.EndInit(); 
      return bi; 
     } 
     return null; 
    } 

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

视图模型

 public Image ImageSrc 
     { 
      get 
      { 
       MemoryStream ms = new MemoryStream(GetImageAsByteArray()); 
       Image img = Image.FromStream(ms); 

       // Here I call method to hide splash screen "Loading" 

       return img; 
      } 
     } 
+1

你它的源属性绑定到您的视图模型的属性?然后,您可以简单地在调用视图模型属性getter时执行操作。 – Clemens

+1

什么是“模型视图”?这些条款准确无误。 –

+0

@Clemens - 设置属性和完成加载不是一回事。 –

回答

0

您可以在后台加载图像,并称之为 “NotifyPropertyChanged” 的形象已经被加载时:

private static Image SplashScreenImage = GetSplashScreenImage(); 
private Image ActualImage = null; 
private bool IsLoading = false; 
public Image ImageSrc 
{ 
    get 
    { 
     if (ActualImage != null) 
      return ActualImage; 

     if (!IsLoading) 
     { 
      IsLoading = true; 
      // start loading image in background 
      Task.Run(() => 
      { 
       MemoryStream ms = new MemoryStream(GetImageAsByteArray()); 
       ActualImage = Image.FromStream(ms); 
      }).ContinueWith(t => PropertyChanged("ImageSrc"), TaskScheduler.FromCurrentSynchronizationContext()); 
     } 
     return SplashScreenImage; 
    } 
} 
+0

我正在使用NET 3.5 SP1,没有可用的任务。 – user1624552

+0

你也可以使用线程代替;) – JanDotNet

+0

这不完全是我想要的。我也不明白你为什么要将启动画面图像返回到图像源。我假装做的是:当我做了很长时间的任务时,我显示一个启动屏幕显示“正在加载...”。这一长期任务包括将图像从高分辨率转换为低分辨率。这就是GetImageAsByteArray。然后,一旦我将图像转换为低分辨率,我想关闭启动画面。我遇到的问题是,一旦调用了OnPropertyChanged(“ImageSrc”)并且启动画面关闭后,图像花费几秒钟时间可见..... – user1624552

-1

您可以使用异步无需转换器绑定:

<Image Source="{Binding ImageSrc, IsAsync=True}"/> 

的ImageSrc属性的getter直接创建一个BitmapFrame或BitmapImage的是这样的:

public ImageSource ImageSrc 
{ 
    get 
    { 
     ImageSource image; 

     using (var stream = new MemoryStream(GetImageAsByteArray())) 
     { 
      image = BitmapFrame.Create(
       stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); 
     } 

     SplashScreenEnabled = false; 
     return image; 
    } 
} 

public bool SplashScreenEnabled { get; set; } // firing PropertyChanged omitted 
-1

如果你想调用指令时, Loaded事件为Image元素触发,您可以使用交互触发器:

<Image Grid.Row="0" 
      Source="{Binding Path=ImageSrc, NotifyOnTargetUpdated=True, Converter={StaticResource imgToSrcConverter}}" 
      Visibility="{Binding ImgVisibility}" 
      RenderTransformOrigin="0,0" 
      SnapsToDevicePixels="True" 
      OverridesDefaultStyle="False" 
      TargetUpdated="targetUpdated" 
      Cursor="Hand" 
      RenderOptions.BitmapScalingMode="LowQuality" 
      RenderOptions.EdgeMode="Aliased" 
      xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="Loaded"> 
      <i:InvokeCommandAction Command="{Binding YourCommand}" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
    <Image.Effect> 
     <DropShadowEffect Opacity="0.8" BlurRadius="8"> 
     </DropShadowEffect> 
    </Image.Effect> 
</Image> 

有关如何通过执行视图模型命令来处理事件的更多信息,请参阅以下博文:https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/

另一种选择可能是简单地从源setter方法执行命令:

public Image ImageSrc 
{ 
    get 
    { 
     MemoryStream ms = new MemoryStream(GetImageAsByteArray()); 
     Image img = Image.FromStream(ms); 

     YourCommandProperty.Execute(null); 

     return img; 
    } 
}