Thursday, March 26, 2009

WPF Fish Eye Effect

Hi,

I had a fantasy for Fish Eye effect, and I always have wondered how I will be able to do it one day. But guess what, it is barely simple. I didnt have to do anything much to do it. I am going to explain here in detail about the concept I followed:

Edited on : < May 20th 5.15 PM > Finally, I have got the way to store my projects with in my office. So please download it from
Here
First of all, in Xaml, I have a listview with the Following Code:



< ListView Name="lvwCharts" ItemsSource="{ Binding }" Margin="0,49,0,0">
< ListView.ItemTemplate>
< DataTemplate>
< Grid Width="250">
< StackPanel>
< Label Background="AliceBlue" HorizontalAlignment="Stretch" BorderBrush="Black" BorderThickness="1"
Content="{Binding Path = Name}" />

< Image Name="imgChart"
Height="{Binding Path = Height}"
Width="{Binding Path = Width}"
Source ="{Binding Path = Path, Converter={StaticResource converter}}"
MouseEnter="imgChart_MouseEnter"
MouseLeave="imgChart_MouseLeave"
MouseLeftButtonDown="imgChart_MouseLeftButtonDown"
HorizontalAlignment="Center"
VerticalAlignment="Center"
MouseWheel="imgChart_MouseWheel"
Margin="0"
/>
< /StackPanel>
< /Grid>
< /DataTemplate>
< /ListView.ItemTemplate>

< /ListView>


For Binding the object with the listview, create a class with the Chart Proxy


Public Class ChartsProxy
Private _name As String
Private _group As String
Private _height As Double = 100
Private _path As String
Private _width As Double = 100

Public Sub New(ByVal name As String, ByVal path As String, ByVal group As String, ByVal height As Double)
_name = name
_group = group
_path = path
End Sub

Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property

Public Property Group() As String
Get
Return _group
End Get
Set(ByVal value As String)
_group = value
End Set
End Property


Public Property Path() As String
Get
Return _path
End Get
Set(ByVal value As String)
_path = value
End Set
End Property

Public Property Height() As Double
Get
Return _height
End Get
Set(ByVal value As Double)
_height = value
End Set
End Property

Public Property Width() As Double
Get
Return _width
End Get
Set(ByVal value As Double)
_width = value
End Set
End Property

End Class


And in your Xaml.vb class add the following two Event handlers



Private Sub imgChart_MouseLeftButtonDown(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs)
Dim img As Image
Dim proxy As ChartsProxy
Dim index As Integer = -1
img = TryCast(sender, Image)

If Not img Is Nothing Then
proxy = GetParent(img)

If Not proxy Is Nothing Then
index = lvwCharts.Items.IndexOf(proxy)
lvwCharts.SelectedIndex = index
End If

End If
lvwCharts.Focus()
lvwCharts.Items.Refresh()
End Sub

Private Sub imgChart_MouseLeave(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseEventArgs)
Dim img As Image
Dim proxy As ChartsProxy

img = TryCast(sender, Image)

If Not img Is Nothing Then
proxy = GetParent(img)

If Not proxy Is Nothing Then
Dim widthAnimation As DoubleAnimation = New DoubleAnimation()
widthAnimation.From = proxy.Width
widthAnimation.To = proxy.Width - 70
proxy.Width = proxy.Width - 70
widthAnimation.Duration = TimeSpan.FromSeconds(0.3)

Dim heightAnimation As DoubleAnimation = New DoubleAnimation()
heightAnimation.From = proxy.Height
heightAnimation.To = proxy.Height - 50
heightAnimation.Duration = TimeSpan.FromSeconds(0.3)
proxy.Height = proxy.Height - 50
img.BeginAnimation(Image.HeightProperty, heightAnimation)
img.BeginAnimation(Image.WidthProperty, widthAnimation)

End If

End If


'lvwCharts.Items.Refresh()

End Sub

Public Function GetParent(ByVal img As Image) As ChartsProxy
Dim proxy As ChartsProxy = Nothing
Dim prop As DependencyObject
Dim presenter As ContentPresenter
Dim bool As Boolean = True

prop = VisualTreeHelper.GetParent(img)

While bool
presenter = TryCast(prop, ContentPresenter)

If (Not presenter Is Nothing) Then

proxy = TryCast(presenter.Content, ChartsProxy)

If Not proxy Is Nothing Then
bool = False
Else
prop = VisualTreeHelper.GetParent(prop)
End If

Else
prop = VisualTreeHelper.GetParent(prop)
End If

End While

Return proxy
End Function


Edited on : < May 15th 2.13 PM > : As I have posted a very basic version here...if you want a complete code then send a mail at vikasbhandari2@gmail.com. I will send you a complete project.

4 comments:

Anonymous said...

What does it look like? Do you have a screenshot ?

Vikas Bhandari said...

Hey there!

I can get u a screenshot but you cannot feel fish eye effect in a screenshot. So you can download the code from the codeplex link I have given in the post. I am working on a complete fish eye listview control and I will be posting it in another week on Codeplex.

Thanks,
Vikas

Omkar said...

Hello Vikas.

I have dopwnloaded your code from codeplex. and run it on my local machine. but it is not working,
I am getting following error.

Cannot create instance of 'Charts' defined in assembly 'VBFishEyeTrial, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation. Error at object 'System.Windows.Controls.Grid' in markup file 'VBFishEyeTrial;component/showimages.xaml' Line 9 Position 10.

I am new bie in wpf devlopement.
so please help me how to sove this problem.

Thanks and Regards
Omkar.

Excel Power said...

Hello Omkar,

Sorry about that. I have uploaded a fresh project here :

http://wpffisheye.codeplex.com/

It is very much stable and does a very nice Fish Eye Effect.

Thanks,
Vikas