0

I know that there have been other questions concerning the CoverFlow effect in WPF. My favourite is Is there a good iTunes coverflow-type control for WPF?.

I downloaded the one "Part 7" and it is in WPF and C#.

Now, I almost never use third party libraries, specially for GUI ones and I don't know how to use that template in my project..

So, basically, how can I include that correctly in my project? What should I do after taking the library in References?

If you know a better CoverFlow template (and free) can you tell me which?

Please Help (a little tip, my project is in VB.NET but I don't think it does matter anything in .dll)

Community
  • 1
  • 1
user1714647
  • 664
  • 2
  • 7
  • 20

1 Answers1

1

The example CoverFlow Component that you are using, doesn't work completely as a standalone control. There is an interface called ThumbnailManager that needs to be Implemented. I was able to get it working in VB by first right clicking on the Toolbox and selecting Choose Items then I navigated to the .dll file that contains the Coverflow component Ded.Tutorial.Wpf.CoverFlow.Part7.FlowComponent.dll and selected it, after which I was able to drop the FlowControl into my MainWindow from the ToolBox. I then converted the C# code that the author had used to create the ThumbnailManager to VB.

ThumbnailManager.vb

Imports System.IO.IsolatedStorage
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging
Imports Ded.Tutorial.Wpf.CoverFlow.Part7.FlowComponent
Imports Ded.Tutorial.Wpf.CoverFlow.Part7.FlowComponent.FlowControl

Namespace Ded.Tutorial.Wpf.CoverFlow.Part7.FlowComponent
    Public Class ThumbnailManager : Implements IThumbnailManager
        Private ReadOnly store As IsolatedStorageFile

        Private Shared Function AmazonCut(myImage As Image) As Image
            If (myImage.Width <> myImage.Height) Then
                Return myImage
            End If
            Dim bmp As Bitmap = New Bitmap(myImage)
            Dim size As Integer = myImage.Height
            Dim white As Integer = System.Drawing.Color.FromKnownColor(KnownColor.White).ToArgb()
            Dim i As Integer = 0
            While (i < size / 2)
                If (Not bmp.GetPixel(i, i).ToArgb().Equals(white)) Then Exit While
                If (Not bmp.GetPixel(i, size - 1 - i).ToArgb().Equals(white)) Then Exit While
                If (Not bmp.GetPixel(size - 1 - i, i).ToArgb().Equals(white)) Then Exit While
                If (Not bmp.GetPixel(size - 1 - i, size - 1 - i).ToArgb().Equals(white)) Then Exit While
                i += 1
            End While
            If (i > 0) Then
                i += 8
                Dim zone As Rectangle = New Rectangle(i, i, size - 2 * 1, size - 2 * i)
                Return bmp.Clone(zone, System.Drawing.Imaging.PixelFormat.DontCare)
            End If
            Return bmp
        End Function

        Private Function GetThumbnail(path As String) As Byte()
            Dim source As Image = Image.FromFile(path)
            source = AmazonCut(source)
            Dim height As Integer = source.Height
            Dim width As Integer = source.Width
            Dim factor As Integer = (height - 1) \ 250 + 1
            Dim smallHeight As Integer = height \ factor
            Dim smallWidth As Integer = width \ factor
            Dim thumb As Image = source.GetThumbnailImage(smallWidth, smallHeight, Nothing, IntPtr.Zero)
            Using ms As New MemoryStream
                thumb.Save(ms, ImageFormat.Png)
                ms.Flush()
                ms.Seek(0, SeekOrigin.Begin)
                Dim result(CInt(ms.Length)) As Byte
                ms.Read(result, 0, CInt(ms.Length))
                Return result
            End Using

        End Function

        Public Sub New()
            store = IsolatedStorageFile.GetUserStoreForAssembly
        End Sub

        Public Function GetThumbnail(host As String, filepath As String) As System.Windows.Media.ImageSource Implements IThumbnailManager.GetThumbnail
            Dim thumbName As String = Path.GetFileName(filepath)
            If (store.GetFileNames(thumbName).Length = 0) Then
                Using Stream As New IsolatedStorageFileStream(thumbName, FileMode.CreateNew, store)
                    Dim data() As Byte = GetThumbnail(filepath)
                    Stream.Write(data, 0, data.Length)
                End Using
            End If
            Using Stream As New IsolatedStorageFileStream(thumbName, FileMode.Open, store)
                Dim myImage As BitmapImage = New BitmapImage()
                myImage.BeginInit()
                myImage.CacheOption = BitmapCacheOption.OnLoad
                myImage.StreamSource = Stream
                myImage.EndInit()
                myImage.Freeze()
                Return myImage
            End Using
        End Function
    End Class
End Namespace

I then added an additional class to the MainWindow.xaml.vb and a Load Method that he was using. I also had to change Ded.Tutorial.Wpf.CoverFlow.Part7.FlowComponent.FlowControl to Global.Ded.Tutorial.Wpf.CoverFlow.Part7.FlowComponent.FlowControl in MainWindow.g.vb after that the component worked.

MainWindow.xaml.vb

Imports System.IO
Imports System.Drawing.Imaging
Imports WpfApplication1.Ded.Tutorial.Wpf.CoverFlow.Part7


Class MainWindow

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        FlowControl1.Cache = New FlowComponent.ThumbnailManager
        Load("C:\Users\Marks-6520\Pictures\Alaska Trip")
        slider.Minimum = 0
        slider.Maximum = FlowControl1.Count - 1
    End Sub

    Public Sub Load(imagePath As String)
        Dim imageDir As DirectoryInfo = New DirectoryInfo(imagePath)
        Dim images As List(Of FileInfo) = New List(Of FileInfo)(imageDir.GetFiles("*.jpg"))
        images.Sort(New FileInfoComparer)
        For Each f As FileInfo In images
            FlowControl1.Add(Environment.MachineName, f.FullName)
        Next
    End Sub


    Private Sub slider_ValueChanged(sender As System.Object, e As System.Windows.RoutedPropertyChangedEventArgs(Of System.Double))

        FlowControl1.Index = Convert.ToInt32(slider.Value)

    End Sub
End Class

Public Class FileInfoComparer : Implements IComparer(Of FileInfo)

    Public Function Compare(x As System.IO.FileInfo, y As System.IO.FileInfo) As Integer Implements System.Collections.Generic.IComparer(Of System.IO.FileInfo).Compare
        Return String.Compare(x.FullName, y.FullName)
    End Function
End Class
Mark Hall
  • 53,938
  • 9
  • 94
  • 111
  • I get errors like "Drawing is not a member of System" "FromFile" is not a member of System.Windows.Controls.Image". You seem to use a not WPF frameworks code but old Windows.Forms. – user1714647 Jan 21 '13 at 22:26
  • @user1714647 That was translated directly from your coverflow example code. You just need to include it in your references. – Mark Hall Jan 22 '13 at 00:10
  • @user1714647 The original author of the control used the System.Drawing namespace in order to use some GDI functions. That is why it is included in the code. – Mark Hall Jan 22 '13 at 06:29
  • Excellent, I made a progress but I have two issues now: Avira takes my programme as Trojan Horse (lol), and I get the error "No thumbnail cache." when I run the programme. I have just set a folder with 3 images. – user1714647 Jan 22 '13 at 14:12
  • @user1714647 are you assigning your Cache in the Forms constructor before you assign your image directory. It should look something like this `FlowControl1.Cache = New FlowComponent.ThumbnailManager` – Mark Hall Jan 23 '13 at 01:34
  • Unfortunately we seem to be to a very different fuse. Anyway VS gives the error "Type 'FlowComponent.ThumbnailManager' not defined" although I have imported the library and the references (in facts I've been able to create the control FlowComponent). And another issue, Avira takes my programme as Trojan Horse and it isn't. It happens since I used your code. – user1714647 Jan 23 '13 at 12:33
  • My code is just a translation of the code from the article there is nothing different. It works on my PC showing the pictures and doesn't trigger my AV. I will post my MainWindow.xaml.vb contents. – Mark Hall Jan 23 '13 at 12:50
  • Please then link that because I'm not able to make it work and have no idea on why Avira takes it as virus. EDIT: I just saw the new code, let me make some try and I'll tell you if it works. – user1714647 Jan 23 '13 at 12:58
  • It gives the same error yet. What else have you added in references? – user1714647 Jan 23 '13 at 13:04
  • Nothing special just the reference that got added when I dropped the Component into the Window. as of right now you have all of the Code from my example program – Mark Hall Jan 23 '13 at 13:07
  • Last comment: Thank you a lot, now it seems to work. I just I'm trying now to make the slider work (because it's not working) – user1714647 Jan 23 '13 at 13:11
  • Make sure you attach the event in the Xaml. i.e. something like this `` – Mark Hall Jan 23 '13 at 13:13
  • I did but it doesn't work. I'm not able to move it with the mouse – user1714647 Jan 23 '13 at 13:21
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/23223/discussion-between-mark-hall-and-user1714647) – Mark Hall Jan 23 '13 at 13:29
  • Now it works. I had just set the maximum before call Load. Thanks a lot. – user1714647 Jan 23 '13 at 13:29