Click here to Skip to main content
15,884,237 members
Home / Discussions / WPF
   

WPF

 
AnswerRe: Animation on DataGridRow jumps to wrong row when scrolling Pin
Gerry Schmitz28-Feb-22 8:11
mveGerry Schmitz28-Feb-22 8:11 
GeneralRe: Animation on DataGridRow jumps to wrong row when scrolling Pin
Mc_Topaz28-Feb-22 20:28
Mc_Topaz28-Feb-22 20:28 
QuestionLabelprint on Thermotransfer Pin
Member 118002289-Feb-22 0:34
Member 118002289-Feb-22 0:34 
QuestionRe: Labelprint on Thermotransfer Pin
Eddy Vluggen9-Feb-22 3:13
professionalEddy Vluggen9-Feb-22 3:13 
QuestionWPF c# onStartUp() view model problem with multiple data inputs Pin
StealthRT5-Feb-22 7:31
StealthRT5-Feb-22 7:31 
AnswerRe: WPF c# onStartUp() view model problem with multiple data inputs Pin
Gerry Schmitz5-Feb-22 18:16
mveGerry Schmitz5-Feb-22 18:16 
AnswerRe: WPF c# onStartUp() view model problem with multiple data inputs Pin
Kevin Marois21-Feb-22 11:29
professionalKevin Marois21-Feb-22 11:29 
QuestionWpf System.Windows.Media.ImageSourcesConverter cannot be applied Pin
StealthRT1-Feb-22 16:08
StealthRT1-Feb-22 16:08 
Hey all it has been a few years since I last worked on my WPF code and sadly I'm not remembering what all I did in order for it to work as its coded.

The current issue I am facing is this:

An object of the type 'System.Windows.Media.ImageSourcesConverter' cannot be applied to a property that expects the type 'System.Windows.Data.IValueConverter'.

It has the above error on this line of code:
<Image Source="{Binding Path,
                Converter={StaticResource ImageSourceConverter}}"
                Stretch="Fill"
/>

The full XAML code being:
<Window.Resources>
     <!-- List of supported animations -->
     <FluidKit:SlideTransition x:Key="SlideTransition" x:Shared="False"/>
     <FluidKit:CubeTransition x:Key="CubeTransition" Rotation="BottomToTop" x:Shared="False"/>
     <FluidKit:FlipTransition x:Key="FlipTransition" x:Shared="False"/>
     <local1:ImageSourceConverter x:Key="ImageSourceConverter"/>
     <!-- Data template for animations -->
     <DataTemplate x:Key="ItemTemplate" x:Shared="False">
         <Image Source="{Binding Path,
             Converter={StaticResource ImageSourceConverter}}"
                Stretch="Fill"/>
     </DataTemplate>
 </Window.Resources>
 <Grid x:Name="imageAreas" HorizontalAlignment="Left" Height="1920" Margin="0,0,0,0" VerticalAlignment="Top" Width="1080" ScrollViewer.VerticalScrollBarVisibility="Disabled">
         <Grid HorizontalAlignment="Left" Height="726" VerticalAlignment="Top" Width="1080" x:Name="topGrid">
             <FluidKit:TransitionPresenter RestDuration="0:0:3"
                                       IsLooped="True"
                                     Transition="{StaticResource FlipTransition}"
                                    ItemsSource="{Binding Images1}"
                                          Width="357"
                                         Height="272"
                            HorizontalAlignment="Left"
                              VerticalAlignment="Top"
                                   ItemTemplate="{StaticResource ItemTemplate}"
                                         x:Name="box1"
                                         Margin="0,0,0,454"/>
             <FluidKit:TransitionPresenter RestDuration="0:0:3"
                                       IsLooped="True"
                                     Transition="{StaticResource FlipTransition}"
                                    ItemsSource="{Binding Images2}"
                                          Width="357"
                                         Height="272"
                            HorizontalAlignment="Left"
                              VerticalAlignment="Top"
                                   ItemTemplate="{StaticResource ItemTemplate}"
                                         x:Name="box2"
                                         Margin="357,0,0,0"/>
   ....ETC....

It is references what I believe is this class (ImageSourceConverter.cs):
/// <summary>
/// This converter automatically disposes image streams as soon as images
/// are loaded, thus avoiding file access exceptions when attempting to delete images.
/// </summary>
public sealed class ImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string path = value as string;
        if (path != null)
        {
            //create new stream and create bitmap frame
            var bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = new FileStream(path, FileMode.Open, FileAccess.Read);
            //load the image now so we can immediately dispose of the stream
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.EndInit();

            //clean up the stream to avoid file access exceptions when attempting to delete images
            bitmapImage.StreamSource.Dispose();

            return bitmapImage;
        }
        else
        {
            return DependencyProperty.UnsetValue;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return DependencyProperty.UnsetValue;
    }
}


My View Model (MainWindowViewModel.cs) is this:
public class MainWindowViewModel : IDisposable
{
    private readonly IDisposable _token1;
    private readonly IDisposable _token2;
    private readonly IDisposable _token3;
    private readonly IDisposable _token4;
    private readonly IDisposable _token5;
    private readonly IDisposable _token6;
    private readonly IDisposable _token7;
    private readonly IDisposable _token8;
    private readonly IDisposable _token9;
    private readonly IDisposable _token10;

    public MainWindowViewModel(IImageSource imageSource)
    {
        // subscribe to update images at regular intervals
        _token1 = imageSource
            .GetImages(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "box1"))
            .ObserveOn(DispatcherScheduler.Current)
            .Subscribe(i => UpdateImages(i, box1), ex => ShowError(ex));

        _token2 = imageSource
            .GetImages(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "box2"))
            .ObserveOn(DispatcherScheduler.Current)
            .Subscribe(i => UpdateImages(i, box2), ex => ShowError(ex));

        _token3 = imageSource
            .GetImages(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "box3"))
            .ObserveOn(DispatcherScheduler.Current)
            .Subscribe(i => UpdateImages(i, box3), ex => ShowError(ex));

        _token4 = imageSource
            .GetImages(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "box4"))
            .ObserveOn(DispatcherScheduler.Current)
            .Subscribe(i => UpdateImages(i, box4), ex => ShowError(ex));

        _token5 = imageSource
            .GetImages(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "box5"))
            .ObserveOn(DispatcherScheduler.Current)
            .Subscribe(i => UpdateImages(i, box5), ex => ShowError(ex));

        _token6 = imageSource
            .GetImages(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "box6"))
            .ObserveOn(DispatcherScheduler.Current)
            .Subscribe(i => UpdateImages(i, box6), ex => ShowError(ex));

        _token7 = imageSource
            .GetImages(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "box7"))
            .ObserveOn(DispatcherScheduler.Current)
            .Subscribe(i => UpdateImages(i, box7), ex => ShowError(ex));

        _token8 = imageSource
            .GetImages(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "box8"))
            .ObserveOn(DispatcherScheduler.Current)
            .Subscribe(i => UpdateImages(i, box8), ex => ShowError(ex));

        _token9 = imageSource
            .GetImages(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "box9"))
            .ObserveOn(DispatcherScheduler.Current)
            .Subscribe(i => UpdateImages(i, box9), ex => ShowError(ex));

        _token10 = imageSource
            .GetImages(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "box10"))
            .ObserveOn(DispatcherScheduler.Current)
            .Subscribe(i => UpdateImages(i, box10), ex => ShowError(ex));
    }

    private void ShowError(Exception ex)
    {
        MessageBox.Show(ex.Message,
                        "Photo Gallery", MessageBoxButton.OK, MessageBoxImage.Error);
    }

    /// <summary>
    /// Updates the animation's images.
    /// </summary>
    /// <param name="images">The images to update with</param>
    /// <param name="animation">The animation to update</param>
    private void UpdateImages(IEnumerable<string> images, ObservableCollection<ImageViewModel> animation)
    {
        animation.Clear();
        foreach (var i in images)
        {
            animation.Add(new ImageViewModel { Path = i });
        }
    }

    /// <summary>
    /// Gets or sets a collection of images used for the first animation.
    /// </summary>
    public ObservableCollection<ImageViewModel> box1 { get; set; } =
        new ObservableCollection<ImageViewModel>();

    /// <summary>
    /// Gets or sets a collection of images used for the second animation.
    /// </summary>
    public ObservableCollection<ImageViewModel> box2 { get; set; } =
        new ObservableCollection<ImageViewModel>();

    /// <summary>
    /// Gets or sets a collection of images used for the third animation.
    /// </summary>
    public ObservableCollection<ImageViewModel> box3 { get; set; } =
        new ObservableCollection<ImageViewModel>();

    /// <summary>
    /// Gets or sets a collection of images used for the fourth animation.
    /// </summary>
    public ObservableCollection<ImageViewModel> box4 { get; set; } =
        new ObservableCollection<ImageViewModel>();

    /// <summary>
    /// Gets or sets a collection of images used for the fifth animation.
    /// </summary>
    public ObservableCollection<ImageViewModel> box5 { get; set; } =
        new ObservableCollection<ImageViewModel>();

    /// <summary>
    /// Gets or sets a collection of images used for the sixth animation.
    /// </summary>
    public ObservableCollection<ImageViewModel> box6 { get; set; } =
        new ObservableCollection<ImageViewModel>();

    /// <summary>
    /// Gets or sets a collection of images used for the seventh animation.
    /// </summary>
    public ObservableCollection<ImageViewModel> box7 { get; set; } =
        new ObservableCollection<ImageViewModel>();

    /// <summary>
    /// Gets or sets a collection of images used for the eighth animation.
    /// </summary>
    public ObservableCollection<ImageViewModel> box8 { get; set; } =
        new ObservableCollection<ImageViewModel>();

    /// <summary>
    /// Gets or sets a collection of images used for the nineth animation.
    /// </summary>
    public ObservableCollection<ImageViewModel> box9 { get; set; } =
        new ObservableCollection<ImageViewModel>();

    /// <summary>
    /// Gets or sets a collection of images used for the tenth animation.
    /// </summary>
    public ObservableCollection<ImageViewModel> box10 { get; set; } =
        new ObservableCollection<ImageViewModel>();

    public void Dispose()
    {
        _token1.Dispose();
        _token2.Dispose();
        _token3.Dispose();
        _token4.Dispose();
        _token5.Dispose();
        _token6.Dispose();
        _token7.Dispose();
        _token8.Dispose();
        _token9.Dispose();
        _token10.Dispose();
    }
}

The IImageSource.cs:
public interface IImageSource
{
    IObservable<IEnumerable<string>> GetImages(string path);
}

And lastly the ImageSource.cs:
public class ImageSource : IImageSource
{
    TimeSpan _pollingInterval;

    public ImageSource(TimeSpan pollingInterval)
    {
        _pollingInterval = pollingInterval;
    }

    public IObservable<IEnumerable<string>> GetImages(string path)
    {
        if (!Directory.Exists(path))
        {
            return Observable.Empty<IEnumerable<string>>();
        }

        try
        {
            return Observable.Create<IEnumerable<string>>(observer =>
            {
                return TaskPoolScheduler.Default.ScheduleAsync(async (ctrl, ct) =>
                {
                    for (; ; )
                    {
                        if (ct.IsCancellationRequested)
                        {
                            break;
                        }

                        try
                        {
                            var images = Directory.GetFiles(path, "*.jpg");
                            observer.OnNext(images);
                        }
                        catch (Exception ex)
                        {
                            observer.OnError(ex);
                            throw;
                        }

                        await ctrl.Sleep(_pollingInterval).ConfigureAwait(false);
                    }
                });
            });
        } catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return null;
        }
    }
}

From what I can remember, It loads up the XAML page there and populates each box with images that correspond to a directory called c:\images\box1...10. But as the error at the top of this says I’m not able to do that even though the program still runs just fine - be it without the images of course.

Would be great if someone could tell me what I was up too ha back those many years.
AnswerRe: Wpf System.Windows.Media.ImageSourcesConverter cannot be applied Pin
Richard Deeming1-Feb-22 21:49
mveRichard Deeming1-Feb-22 21:49 
GeneralRe: Wpf System.Windows.Media.ImageSourcesConverter cannot be applied Pin
StealthRT2-Feb-22 2:39
StealthRT2-Feb-22 2:39 
GeneralRe: Wpf System.Windows.Media.ImageSourcesConverter cannot be applied Pin
Richard Deeming2-Feb-22 2:44
mveRichard Deeming2-Feb-22 2:44 
Question(beginner) There must be a better way (TextBlock properties) Pin
Maximilien26-Jan-22 5:08
Maximilien26-Jan-22 5:08 
AnswerRe: (beginner) There must be a better way (TextBlock properties) Pin
Richard Deeming26-Jan-22 5:33
mveRichard Deeming26-Jan-22 5:33 
GeneralRe: (beginner) There must be a better way (TextBlock properties) Pin
Maximilien26-Jan-22 9:10
Maximilien26-Jan-22 9:10 
QuestionConverting a byte[] to a ImageSource means huge memory leak Pin
Starwer24-Jan-22 11:42
Starwer24-Jan-22 11:42 
AnswerRe: Converting a byte[] to a ImageSource means huge memory leak Pin
Gerry Schmitz24-Jan-22 16:15
mveGerry Schmitz24-Jan-22 16:15 
GeneralRe: Converting a byte[] to a ImageSource means huge memory leak Pin
Starwer24-Jan-22 19:58
Starwer24-Jan-22 19:58 
GeneralRe: Converting a byte[] to a ImageSource means huge memory leak Pin
Gerry Schmitz24-Jan-22 21:26
mveGerry Schmitz24-Jan-22 21:26 
GeneralRe: Converting a byte[] to a ImageSource means huge memory leak Pin
Starwer25-Jan-22 7:56
Starwer25-Jan-22 7:56 
AnswerRe: Converting a byte[] to a ImageSource means huge memory leak Pin
Richard Deeming25-Jan-22 21:51
mveRichard Deeming25-Jan-22 21:51 
GeneralRe: Converting a byte[] to a ImageSource means huge memory leak Pin
Starwer26-Jan-22 9:10
Starwer26-Jan-22 9:10 
GeneralRe: Converting a byte[] to a ImageSource means huge memory leak Pin
Gerry Schmitz27-Jan-22 6:33
mveGerry Schmitz27-Jan-22 6:33 
GeneralRe: Converting a byte[] to a ImageSource means huge memory leak Pin
Starwer27-Jan-22 20:29
Starwer27-Jan-22 20:29 
GeneralRe: Converting a byte[] to a ImageSource means huge memory leak Pin
lmoelleb3-Feb-22 4:58
lmoelleb3-Feb-22 4:58 
GeneralRe: Converting a byte[] to a ImageSource means huge memory leak Pin
Starwer5-Feb-22 0:28
Starwer5-Feb-22 0:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.