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