2017-10-05 42 views
-2

J'ai un contrôle d'image WPF à mon avis. Lorsque l'image est chargée, je veux déclencher un événement qui est défini et exécuté dans ma vue de modèle. Comment puis-je faire ceci? Je ne sais pas comment faire cela en utilisant une commande.MVVM WPF Commande de feu lorsque l'image a été chargée (sur un événement chargé)

<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> 

Converter:

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(); 
    } 
} 

Voir modèle:

 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

Avez-vous lier sa propriété Source à une propriété dans votre modèle de vue? Ensuite, vous pouvez simplement effectuer une action lorsque la propriété de modèle de vue getter est appelée. – Clemens

+1

Qu'est-ce qu'une "vue de modèle"? Il est avantageux d'être précis avec ces termes. –

+0

@Clemens - définir la propriété et terminer le chargement ne sont pas la même chose. –

Répondre

0

Vous pouvez charger l'image en arrière-plan et appeler "NotifyPropertyChanged" lorsque l'image a été chargée:

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

J'utilise NET 3.5 SP1, aucune tâche disponible. – user1624552

+0

Vous pouvez également utiliser un fil à la place;) – JanDotNet

+0

Ce n'est pas exactement ce que je veux. En outre, je ne comprends pas pourquoi vous retournez l'image de démarrage à la source de l'image. Ce que je fais semblant de faire est: Pendant que je fais une longue tâche, je montre un écran de démarrage montrant "Chargement ...".Cette longue tâche consiste à convertir une image de haute résolution en basse résolution. C'est ce que fait GetImageAsByteArray. Ensuite, une fois que j'ai converti l'image à une basse résolution, je veux fermer l'écran de démarrage. Le problème que j'ai est qu'une fois OnPropertyChanged ("ImageSrc") est appelé et après que l'écran de démarrage soit fermé, l'image passe plusieurs secondes visible ..... – user1624552

-1

Vous pouvez utiliser un moteur asynchrone de liaison sans convertisseur:

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

Le getter de la propriété IMAGESRC crée directement un BitmapFrame ou BitmapImage comme ceci:

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

Si vous voulez invoquer une commande lorsque le Loaded événement pour les incendies d'élément Image, vous pouvez utiliser un déclencheur d'interaction:

<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> 

Pour plus d'informations sur la gestion des événements en exécutant les commandes de modèle d'affichage, reportez-vous à l'article suivant: https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/.

Une autre option peut être d'exécuter simplement la commande du poseur de votre propriété source:

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

     YourCommandProperty.Execute(null); 

     return img; 
    } 
}