Monday, March 30, 2009

Using WithEvents in Vb.Net

Hi,

Using withEvents in VB.net is very easy. I faced lot of problem while accessing the events. For example, activating a chart does not fire a selection change event. I had to do something like whenever I select my chart, my custom menu should appear. I couldn't find doing it in C#(please send a mail if you find it), but in VB.Net it is very easy.

So to take a small example, I have taken a scenario, if I select any of the chart in my workbook, it should display a message. So first of all I created a Class ProxyCharts. The purpose of the class is to serve a Wrapper for Charts Object. This is the class where we will bind our chart objects to WithEvent keyword. So as a wrapper, we will have as many Wrappers as the number of charts available in the workbook. The proxy chart is as follows:

Public Class ProxyCharts
Private WithEvents _Charts As Chart

Public WriteOnly Property _Chart() As Chart
Set(ByVal value As Chart)
_Charts = value
End Set
End Property

Private Sub _Charts_Activate() Handles _Charts.Activate
MsgBox(_Charts.Name, MsgBoxStyle.Exclamation, "ActivatedChart")
End Sub
End Class


Now we have to bind every chart in the workbook with the ProxyChart. So I added a WorkbookOpen method in my AddIn, which loops to all the charts in the opened workbook.

Private Sub _App_WorkbookOpen(ByVal Wb As Microsoft.Office.Interop.Excel.Workbook) Handles _App.WorkbookOpen

Dim chrtCol As Object
Dim chtCollection As Collection
Dim chrtObj As ChartObjects

For Each wkSht As Worksheet In Wb.Worksheets
chrtCol = wkSht.ChartObjects(Type.Missing)
chrtObj = TryCast(chrtCol, ChartObjects)

If Not chrtObj Is Nothing Then
For Each chrt As ChartObject In chrtObj
Dim chh As New ProxyCharts()
chh._Chart = chrt.Chart
Next chrt
End If
Next wkSht
End Sub



As soon as a workbook is opened, the WorkbookOpen method is called by default and binds all the charts in the opened workbook with ProxyChartType. After binding, the above code will display a message as soon as you select any of the pre existing charts in workbook.

Hope this helps.

Thanks,
Vikas

Thursday, March 26, 2009

Linq Example for Group Join

Hi All,

I have just started bringing LINQs to my work, and learning some new things. So I thought I will store it here before I forget it ;)

I had a simple problem, where in I had to loop through a list of files and to get out few Extensions. For example, If I have a list of around 500 files in the drive, I need to get the files with some valid extension, for eg, Images. So for that, I created a files list with the name of fileList and created an array with the valid extensions. I named that array by IMAGES.

Now to get the list of files with valid extensions I used the following code:


Dim result = From s In fileList Group Join p In IMAGES On s.Extension.ToUpper() Equals p.ToUpper() _ Into Group From p In Group Select s

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.

Tuesday, March 24, 2009

Word 2003 Style Tracking Issue

In word 2003 or ealier versions, whenever we format a text on which a style is already applied, a new style is added in the Styles list and it keeps on increasing if we dont delete it. However, we can stop this automatic tracking and the automatic addition of styles will be disabled. For disabling the automatic addition of styles, go to Tools-->Options --> Edit tab and uncheck "Keep Track of Formatting" option. It is shown in the figure below




Thanks,
Vikas

Thursday, March 19, 2009

Filter using Predicate (WPF)

In WPF, XAML has changed the traditional way of creating and validation the form fields. For example, what if we want to display few of the items in a listview? And what if we want to give user an option to view the items with in the listview?

Without WPF, we will create the loop through all the items and will hide/show the items accordingly. But with WPF, we can do it very easily. I will explain in the following example.

Create a class SampleClass with Two Properties, Name(of string type) and Visible(of boolean type)

Create an ObservableCollection of type SampleClass in your Xaml.cs.

Code : ObservableCollection< SampleClass > collection = new ObservableCollection ()

Add few Items :

collection.Add(new SampleClass("Vikas", true));
collection.Add(new SampleClass("Sonia", true));
collection.Add(new SampleClass("Viman", False));
collection.Add(new SampleClass("Krishna", False));

Add the collection to our listview

myListView.DataContext = collection.

Now, for having a smooth access on filtering, sorting etc features, we will need to get the ICollectionView(Click to know more about ICollectionView) object out of out observable collection.

ICollectionView view = CollectionViewSource.GetDefaultView(collection);

now, to apply the filter we can use the following line anywhere in the code where in we want to put a filter on:

view.Filter = delegate(object item)
{
SampleClass sItem = item as SampleClass;
bool retValue = false;

if(sItem!=null)
{
retValue = sItem.Visible;
}

return retValue;
}

We can do the above step by using a new method with the predicate as well.

private bool GetVisibleState(object item)
{
SampleClass sItem = item as SampleClass;
bool retValue = false;

if(sItem!=null)
{
retValue = sItem.Visible;
}

return retValue;
}

And add the filter like following :

view.Filter = new Predicate< object >(GetVisibleState);

The above code will show the items in which the Visible property is set to true.

The code in VB.net is as follows :


Dim view As ICollectionView
Dim collection As ObservableCollection(Of SampleClass) = New ObservableCollection(Of SampleClass)

collection.Add(New SampleClass("Vikas", True))
collection.Add(New SampleClass("Sonia", True))
collection.Add(New SampleClass("Viman", False))
collection.Add(New SampleClass("Krishna", False))

myListView.DataContext = collection


view = CollectionViewSource.GetDefaultView(collection)
view.Filter = New Predicate(Of Object)(AddressOf FilterItems)



Private Function FilterItems(ByVal param As Object) As Boolean

Dim proxy As SampleClass
Dim Name As String
Dim retValue As Boolean

Name = combovalue ' (some arbit value, which you want to use as a filter. Example, the if you want to filter the value if the name is vikas, then say name = "Vikas")

proxy = TryCast(param, SampleClass)
retValue = proxy.Show

Return retValue

End Function


Public Class SampleClass
Private _name As String
Private _show As Boolean

Public Sub New(ByVal name As String, ByVal show As Boolean)
_name = name
_show = show
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 Show() As Boolean
Get
Return _show
End Get
Set(ByVal value As Boolean)
_show = value
End Set
End Property
End Class

Wednesday, March 18, 2009

How to Use Linqs in VB.Net

With the new versions of Visual Studios, we have got the Power of LINQ(Language INtegrated Query). With the help of LINQ, we can make query on any collection like we do in SQL. What if we want to search if a string is present in an array or not. Let me explain this in an example :

I have a string Array :

Dim validXLExtns() As String = {"XLS", "XLSX", "XLA", "XLAM", "XLSM", "XLTX", "XLT", ""}


Now, I have to check programmatically if "XLS" exists in the array or not. Ideally, you will like to loop through the items in the array. But, now, with the help of LINQs you can do it with the following command :

Dim product = From s In validXLExtns _
Where s = "XLS"


And if product.count is greater than 0, the value actually exists in the array.


Some very good examples of LINQs:

Developer.com
MSDN LINQ Examples