1 - Utiliser le Contrôle PictureBox (WinForm).
On commence tout d'abord par ajouter les références nécessaires au projet :
- WindowsFormsIntegration
- System.Windows.Forms
Puis on définit System.Windows.Forms dans le namespace en XAML :
xmlns:wfc="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Puis le code XAML nous donne :
<Grid> <WindowsFormHost Height="100" Width="100"> <wfe:PictureBox x:Name="pictureBox1" Height="100" Width="100" ImageLocation="C:\Users\UserID\MesImages\Blog.gif"/> </WindowsFormHost> </Grid>
Pour rappel la PictureBox ne gère pas les URI donc pour alimenter votre PictureBox avec une image stockée sur le Web, on l'alimente dans le code behind comme ceci:
Public MainWindow() { InitializeComponent(); Uri url = new Uri("http://t0.gstatic.com/images?q=tbn:ANd9GcSAheOd0oNGdBUtJhTMSDz08_9lpW8rgg2_TBFi3DMAVfsgYYRU4g"); pictureBox1.Image = System.Drawing.Image.FromStream(System.Net.HttpWebRequest.Create("url").GetResponse().GetResponseStream()); }
Ce n'est pas une solution que j'affectionne dans la mesure où l'on utilise une technologie "ancienne génération" dans une IHM WPF et que l'on place un contrôle non vectoriel dans un container, lui-même dans une IHM vectorielle.
2 - Utiliser une Classe dédiée aux Gifs
Cette classe, je ne l'ai pas écrite moi même, je l'ai trouvée ici.
Elle permet :
- d'afficher des gifs animés tout en ayant les images en "Embedded Resource".
- Les gifs s'affichent et s'animent directement dans l'IDE (c'est le cas dans VS2010) et à l'exécution bien évidemment. :)
- Lors de l’exécution un clic de souris permet d'arrêter le gif :
public class GIFImageControl : Image { public static readonly DependencyProperty AllowClickToPauseProperty = DependencyProperty.Register("AllowClickToPause", typeof (bool), typeof (GIFImageControl), new UIPropertyMetadata(true)); public static readonly DependencyProperty GIFSourceProperty = DependencyProperty.Register("GIFSource", typeof (string), typeof (GIFImageControl), new UIPropertyMetadata("", GIFSource_Changed)); public static readonly DependencyProperty PlayAnimationProperty = DependencyProperty.Register("PlayAnimation", typeof (bool), typeof (GIFImageControl), new UIPropertyMetadata(true, PlayAnimation_Changed)); private Bitmap _Bitmap; private bool _mouseClickStarted; public GIFImageControl() { MouseLeftButtonDown += GIFImageControl_MouseLeftButtonDown; MouseLeftButtonUp += GIFImageControl_MouseLeftButtonUp; MouseLeave += GIFImageControl_MouseLeave; Click += GIFImageControl_Click; //TODO:Future feature: Add a Play/Pause graphic on mouse over, and possibly a context menu } public bool AllowClickToPause { get { return (bool) GetValue(AllowClickToPauseProperty); } set { SetValue(AllowClickToPauseProperty, value); } } public bool PlayAnimation { get { return (bool) GetValue(PlayAnimationProperty); } set { SetValue(PlayAnimationProperty, value); } } public string GIFSource { get { return (string) GetValue(GIFSourceProperty); } set { SetValue(GIFSourceProperty, value); } } private void GIFImageControl_Click(object sender, RoutedEventArgs e) { if (AllowClickToPause) PlayAnimation = !PlayAnimation; } private void GIFImageControl_MouseLeave(object sender, MouseEventArgs e) { _mouseClickStarted = false; } private void GIFImageControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (_mouseClickStarted) FireClickEvent(sender, e); _mouseClickStarted = false; } private void GIFImageControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { _mouseClickStarted = true; } private void FireClickEvent(object sender, RoutedEventArgs e) { if (null != Click) Click(sender, e); } public event RoutedEventHandler Click; private static void PlayAnimation_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) { var gic = (GIFImageControl) d; if ((bool) e.NewValue) { //StartAnimation if GIFSource is properly set if (null != gic._Bitmap) ImageAnimator.Animate(gic._Bitmap, gic.OnFrameChanged); } else //Pause Animation ImageAnimator.StopAnimate(gic._Bitmap, gic.OnFrameChanged); } private void SetImageGIFSource() { if (null != _Bitmap) { ImageAnimator.StopAnimate(_Bitmap, OnFrameChanged); _Bitmap = null; } if (String.IsNullOrEmpty(GIFSource)) { //Turn off if GIF set to null or empty Source = null; InvalidateVisual(); return; } if (File.Exists(GIFSource)) _Bitmap = (Bitmap) System.Drawing.Image.FromFile(GIFSource); else { //Support looking for embedded resources Assembly assemblyToSearch = Assembly.GetAssembly(GetType()); _Bitmap = GetBitmapResourceFromAssembly(assemblyToSearch); if (null == _Bitmap) { assemblyToSearch = Assembly.GetCallingAssembly(); _Bitmap = GetBitmapResourceFromAssembly(assemblyToSearch); if (null == _Bitmap) { assemblyToSearch = Assembly.GetEntryAssembly(); _Bitmap = GetBitmapResourceFromAssembly(assemblyToSearch); if (null == _Bitmap) throw new FileNotFoundException("GIF Source was not found.", GIFSource); } } } if (PlayAnimation) ImageAnimator.Animate(_Bitmap, OnFrameChanged); } private Bitmap GetBitmapResourceFromAssembly(Assembly assemblyToSearch) { string[] resourselist = assemblyToSearch.GetManifestResourceNames(); if (null != assemblyToSearch.FullName) { string searchName = String.Format("{0}.{1}", assemblyToSearch.FullName.Split(',')[0], GIFSource); if (resourselist.Contains(searchName)) { Stream bitmapStream = assemblyToSearch.GetManifestResourceStream(searchName); if (null != bitmapStream) return (Bitmap)System.Drawing.Image.FromStream(bitmapStream); } } return null; } private static void GIFSource_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((GIFImageControl) d).SetImageGIFSource(); } private void OnFrameChanged(object sender, EventArgs e) { Dispatcher.BeginInvoke(DispatcherPriority.Normal, new OnFrameChangedDelegate(OnFrameChangedInMainThread)); } private void OnFrameChangedInMainThread() { if (PlayAnimation) { ImageAnimator.UpdateFrames(_Bitmap); Source = GetBitmapSource(_Bitmap); InvalidateVisual(); } } [DllImport("gdi32.dll", EntryPoint = "DeleteObject")] public static extern IntPtr DeleteObject(IntPtr hDc); private static BitmapSource GetBitmapSource(Bitmap gdiBitmap) { IntPtr hBitmap = gdiBitmap.GetHbitmap(); BitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); DeleteObject(hBitmap); return bitmapSource; } private delegate void OnFrameChangedDelegate(); }
Cette classe a été pour moi sur plusieurs petits projets une bonne solution.
3- Créer son gif en WPF
Au bout d'un moment, on utilise quoi ? WPF ! On sait faire des animations avec WPF ? Oui, évidemment ! Alors, la solution consiste à créer d'un côté toute les images qui composent votre gif et de l'autre à créer un storyboard :
<Image Name="Image1"> <Image.Triggers> <EventTrigger RoutedEvent="Image.Loaded" <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <ObjectAnimationUsingKeyFrames Duration="0:0:1" Storyboard.TargetProperty="Source" RepeatBehavior="Forever"> <DiscreteObjectKeyFrames KeyTime="0:0:0"> <DiscreteObjectKeyFrame.Value> <BitmapImage UriSource="Images/Image1.gif"/> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrames> <DiscreteObjectKeyFrames KeyTime="0:0:0.2"> <DiscreteObjectKeyFrame.Value> <BitmapImage UriSource="Images/Image2.gif"/> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrames> <DiscreteObjectKeyFrames KeyTime="0:0:0.4"> <DiscreteObjectKeyFrame.Value> <BitmapImage UriSource="Images/Image3.gif"/> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrames> <DiscreteObjectKeyFrames KeyTime="0:0:0.6"> <DiscreteObjectKeyFrame.Value> <BitmapImage UriSource="Images/Image4.gif"/> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrames> <DiscreteObjectKeyFrames KeyTime="0:0:0.8"> <DiscreteObjectKeyFrame.Value> <BitmapImage UriSource="Images/Image5.gif"/> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrames> <DiscreteObjectKeyFrames KeyTime="0:0:1"> <DiscreteObjectKeyFrame.Value> <BitmapImage UriSource="Images/Image6.gif"/> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrames> </ObjectAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Image.Triggers> </Image>
Evidemment ici on est clairement dans le cas figure où soit vous, soit votre équipe maîtrise en intégralité la phase design.
Voilà, maintenant vous avez toutes les cartes en main.
Bonne Journée.
Jai rien compris comment fallait faire.....
RépondreSupprimerDites moi ce que vous n'avez pas compris afin de vous apporter mon aide. Que cherchez vous à faire ? Dans quel contexte ?
RépondreSupprimerJ'aimerais utiliser une gif en background , si tu peux m'aider
RépondreSupprimer