|
The newsletter is compiled by DevCity.NET NewsMasters XTab and Mike McIntyre Advertisement
Get .NET Code Here!
GetDotNetCode offers inexpensive, well tested, quality and royalty free .NET source code. Our packages are VS.NET projects, well commented and informative. Run the demo, study the code, save time, learn, and be more productive!
Click here for our FREE code offering.
Table Of Content:
Advertisement
If you want to get your hands on a great collection of commented, real world, fully working VB.NET Solutions for a whole range of coding needs, then make sure that you check out next month's Newsletter competition. Simply by answering an easy question you'll have the chance to win a stack of the superb frustrating-busting packages from GetDotNetCode.Com. These code packages show you in seconds what can take you hours, if not days, to work out from books and internet searches.
Three lucky competition winners will be able to pick a selection of packages of their own choice from the site. The topics available from GetDotNetCode include a massive choice ranging from "Add Images to Menu Items" to "Windows Forms TreeView Drag and Drop", with lots of useful topics in between.
So watch out for the new competition coming soon. If you want to check out the site in the meantime, point your browser to the GetDotNetCode site to see what you can win.
Something that I only recently got the hang of is the difference between the System.IO.File class and the System.IO.FileInfo class. Of course, you might already be well into the swing of it, but concepts like Shared and Static were for a long time - I'm sorry to admit - on that rather long list of things that I pretty much completely ducked out of in VB6. Like OOP. And other stuff that I'm having to get my head round now that I'm truly a wannabe dotNetter.
To be perfectly honest with you, at first I couldn't really see why they had to include what seemed to be two variations of the same thing. They're not exactly a million miles apart, are they? But after a while I did get to see that there are some subtle differences.
In my very non-technical way I Think of the File Class as a single generic file manipulation object that I can use and share in my project. So, for instance, if I want to copy a file between two folders, I could use the File.Copy method to do this. But the File Object stays aloof from the individual files themselves; it never really needs to have more than a passing conversation with the files it handles. For example, you can copy a file using code such as:
File.Copy("C:\Test.txt", "C:\TestBackUp.bak", True)
and it will happily copy that named file, without ever taking any serious notice of what its name is. (If you try this, don't forget to include the Imports System.IO statement.)
And if there was a way of asking that File Object right now which file it had just copied, it wouldn't know. You can immediately instruct it to go off and carry out another File method, dealing with a completely different file and it would be quite happy to go away and do just that, having no recollection of the file it had just dealt with and abandoned.
The FileInfo object, on the other hand, is a lot more up front and personal. It wants to know just exactly which file I want it to deal with. None of this looking away and holding files at arms length business. You instantiate a FileInfo object, assign it one particular file and it will stick all the way with that one file. This obviously makes the FileInfo object the better choice if you are going to be carrying out a number of manipulations on the same file.
In fairness, it has to be said that most of the common things you need to do with or to files can be done with either the File Class or the FileInfo Class. But FileInfo can help you write shorter code and gives you easy access to some properties, such as file length, parent directory and file extension, which you have to jump through some unnecessary hoops to get at if you use a File object instead.
All in all, it's been a good week for this particular .NET Newbie, really. I even answered someone else's question about Classes and Properties. Well, their first question, anyway. Had to back off once we got to the heavy stuff, but still, it's a small step in the right direction, isn't it?
I also learned how to use the Windows Class Viewer this week. Some of those weird looking C# descriptions are actually beginning to make sense to me now! I still have to keep going back to my examples fairly often, but I can see how it might become a very useful tool as I get more ambitious and begin to look for Classes in the .Net Framework that may help me to do something I want to do in particular.
So I've added quite a lot to my dotNet info this week - OOP info, WinCV info and, of course, not forgetting good old FileInfo.
- Junior (Ged Mead aka XTab, xtab@vbcity.com)
by Mike McIntyre
Part 1:
The DataView class is very important to every ADO.NET programmer. Don't overlook the necessity, flexibility, and power of the DataView class.
Consider this important fact: When a DataTable is bound to a form control, a DataView object is used as a "middleman" - whether the programmer explicitly codes it or not. If you do not code it, the binding process uses the DataTable's default DataView behind the scene. Here is a simple diagram showing the relationship that is established when a DataTable is bound to a DataGrid control:
DataTable <-> DataView <-> DataGrid
Because of the fact above you must understand the role the DataView "middleman" plays in binding to master DataTable-to-form control binding. To sort, filter, search, edit, or navigate a DataTable bound to form controls, a DataView is the best object for the job. For example, using the DataView "middleman" to access and manipulate a DataTable bound to a Windows Forms DataGrid is more effective than the round-about approach of using the properties and methods of the DataGrid.
This four part DevCity.NET newsletter will help you understand and learn how to make the DataView "middleman" work to your advantage when binding DataTables to Windows Forms controls.
.NET Help Definition: DataView Class
"A DataView represents a databindable, customized view of a DataTable for sorting, filtering, searching, editing, and navigation."
Basic DataView Concepts
A DataView object provides a view of the rows contained in one DataTable object. Only one DataTable is assigned to a DataView. The resulting view can be sorted, filtered, and searched. The DataTable assigned to the DataView can be edited and navigated through the view.
A major function of the DataView is to allow a DataTable to be bound to both Windows Form controls. A DataTable is bound to Windows control(s) through a DataView.
If you do not know that a DataView gets placed between a DataTable and a form control during binding, it may have seemed that you have been binding your DataTables directly to form controls. After all, you can write code like this that appears to directly bind a DataTable to a DataGrid:
DemoDataGrid.DataSource = DemoDataSet.Tables("Product")
However, when the code above is run, behind the scenes .NET will retrieve the Product table's DefaultView (a DataView) and bind the DemoDataGrid control to that DataView, not directly to the Product table. In other words, if you do not provide a DataView object for binding a DataTable to a form control, .NET will use that DataTable's DefaultView to complete the binding.
Demonstration One
This first DataView demonstration will show how to explicitly bind a DataTable's DefaultView to a DataGrid and how to sort the DefaultView to change the order of the data shown in the DataGrid.
For demonstration purposes please assume the following things exist:
1. A DataSet named DemoDataSet
2. In DemoDataSet a DataTable named Product
3. In Product DataTable this data:
| ProdId | ProdName | ProdCategory |
| 1 | Banana | Fruit |
| 2 | Apple | Fruit |
| 3 | Green Bean | Vegetable |
| 4 | Spinach Noodle | Pasta |
|
4. A Windows Form named ProductForm
5. On the ProductForm a DataGrid named ProductDataGrid
EXAMPLE: Create a DataView variable and to it assign the Product table's DefaultView.
' Declare a variable of type DataView named _ProductDataView.
' Assign DemoDataSet's Product table's DefaultView to
' the _ProductDataView variable.
Dim _ProductDataView As DataView = _
AppMgr.DemoDataSet.Tables("Product").DefaultView
EXAMPLE: Make _ProductDataView the DataSource for the ProductDataGrid.
' Set the ProductDataGrid's DataSource
' to _ProductDataView.
ProductDataGrid.DataSource = _ProductDataView
EXAMPLE: Run the ProductForm. The ProductDataGrid will show:
| ProdId | ProdName | ProdCategory |
| 1 | Banana | Fruit |
| 2 | Apple | Fruit |
| 3 | Green Bean | Vegetable |
| 4 | Spinach Noodle | Pasta |
|
EXAMPLE: Sort the _ProductDataView by setting the DataView object's Sort property.
' Sort _ProductDataView to change
' the order of the data presented in the ProductDataGrid.
_ProductDataView.Sort = "ProdName"
Result: ProductDataGrid shows Product data sorted by ProdName.
| ProdId | ProdName | ProdCategory |
| 2 | Banana | Fruit |
| 1 | Apple | Fruit |
| 3 | Green Bean | Vegetable |
| 4 | Spinach Noodle | Pasta |
|
To learn more about the DataView class visit the links below:
DataView Class
DataView Members
Next issue: Filter, Search, Navigate, and Change a DataTable through a DataView object.
by Mike McIntyre
You can leverage much of your VB6 knowledge to help you develop in VB.Net, and DevCity Leader Mike McIntyre helps you avoid some pitfalls as you make the move.
Some data types in previous versions of Visual Basic have been updated or eliminated in Visual Basic.NET to make VB.NET compatible with the other .NET programming languages and the .NET runtime.
These changes in data types will affect how you declare, use, or convert some data types.
Def Statements
The Visual Basic 6.0, Deftype statements - DefBool, DefByte, DefCur, DefDate, DefDbl, DefDec, DefInt, DefLng, DefObj, DefSng, DefStr, and DefVar are not supported in VB.NET.
Though there is no direct replacement for the Def statements in VB.NET you may find a new feature of VB.NET helpful. If you need to declare a group of variables to be of the same data type you can declare them in one long code line. Here is an example:
Dim player1Score, player2Score, player3Score, player4Score As Integer
In VB6 only the player4Score variable would be typed as Integer, the other variables would be typed as Variant. In VB.NET all the variables will be typed as Integers.
Currency Data Type
The VB6 Currency data type is not supported in VB.NET. Instead, use the new Decimal data type for calculations involving money and for fixed-point calculations. The Decimal data type can handle more digits on both sides of the decimal point. Here is an example Decimal type variable declaration:
Dim invoiceAmount As Decimal
Date Data Type
In VB6 a Date is stored in a Double format using eight bytes. In Visual Basic.NET, the Date data type uses the .NET common language runtime DateTime data type, which is an eight-byte integer value.
Besides the change from using eight bytes to using an eight-byte integer, there are many new properties and methods available from VB.NET Date type. You can gain some productivity by using these new features. To learn more click here.
NOTE: If you must work with VB6 data of type Date in a VB.NET program be aware of this: Because of these different representations, there is no implicit conversion between the Date and Double data types. To convert between a VB.NET Date type and the Visual Basic 6.0 Date type, use the specialized ToOADate and FromOADate methods of the DateTime structure in the .NET System namespace.
Variant Data Type
The VB6 Variant data type is replaced by the Object data type in VB.NET.
The Object data type is .NET's universal data type. It can hold data of any other data type. Visual Basic.NET documentation says that all the functionality of the VB6 Variant type is supplied by the VB.NET Object data type.
WARNING: Be aware that you should avoid using the Object data type whenever possible in .NET code. It causes poor performance and makes program code very hard to read. The use of the new VB.NET OPTION STRICT feature will help you avoid over-using the Object data type. Learn more about OPTION STRICT by clicking here.
One note about using Variant in VB6 vs. Object in VB.NET:
In VB6 if two Variant variables containing integers are multiplied, an overflow condition causes the data type of the result to be changed to Double.
In VB.NET if multiplication of two Object variables containing integers results in an overflow, the result is changed to the .NET 64-bit Long data type.
LSet and RSet
.NET enforces type-safe data. The LSet and RSet statements are not supported in VB.NET because they result in a type-unsafe operation, particularly with structures, which would result in unverifiable code.
Replace your use of the LSet and RSet statements with the .NET String class's SubString method. To learn more about the SubString method click here.
by John Spano
Continuing our look at Reflection from the last Newsletter, now we will examine the main working code in our EXE. It will load our standard class in the list box and then search for classes in our plug-in DLL that implement our interface and load them also.
To show that it picks up only classes that implement IshowInListBox, I created another class that doesn't implement it and placed it in the DLL also. Its definition is very simple and is as follows:
Public Class NonListItem
End Class
And now our main EXE:
Imports System.Reflection
Imports ReflectionInterfaces
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim myCls As MyListItem = New MyListItem
lstListBox1.DisplayMember = "TextValue"
lstListBox1.Items.Add(myCls)
LoadFromFoundDll()
End Sub
Private Sub LoadFromFoundDll()
Dim assemblyObj As Reflection.Assembly = Reflection.Assembly.LoadFrom( _
"C:\VBNet Projects\ReflectionArticle\bin\ReflectionDll.Dll")
Dim types() As Type
Dim FoundInterface As Type
Dim o As Object
types = assemblyObj.GetTypes
For Each tp As Type In types
Try
FoundInterface = tp.GetInterface("IShowInListBox")
If Not FoundInterface Is Nothing Then
o = assemblyObj.CreateInstance(tp.FullName)
Dim oLst As IShowInListBox
oLst = DirectCast(o, IShowInListBox)
lstListBox1.Items.Add(oLst)
End If
Catch
Finally
FoundInterface = Nothing
End Try
Next
End Sub
Private Sub lstListBox1_DoubleClick(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles lstListBox1.DoubleClick
Dim oLst As IShowInListBox
Dim Lst As ListBox
Lst = DirectCast(sender, ListBox)
oLst = DirectCast(Lst.SelectedItem, IShowInListBox)
oLst.SayHello()
End Sub
It's a single form with a list box on it. I have added a reference to my interface DLL and the corresponding imports for it and also for System.Reflection to get our reflection classes we will use. Now to explain the high points of the code.
If we start in the form load event, you see that I am setting up a new instance of my standard class and adding it to the list box. The key thing to notice here is that I am adding the entire object and not just the text from its property. This is one of .NET's major strong points. I can assign anything to the list box, even whole objects, and pull them out later. I also tell the list box to display the TextValue property of any object that is loaded into it. How do you think it displays text of object that it only knows the name of the property of? If you said reflection you're right! It uses it internally also to dynamically call the property you specify. After loading the standard class we then call a function that will load our plug-in class.
In our LoadFromFoundDll we hard code the name of the DLL for simplicity. You could change this to search the application's path for all DLL's that have classes in them that implement our interface or have it look in the registry for the paths and names of the DLL's it is supposed to load to make it more useful.
First we want to load our DLL in to memory using the assembly class. After it's loaded, we can query the DLL for all its classes, which we do by asking for its types and loading them into an array. We then loop through the array and query it to see if it supports our interface. If it does we create an object of the class and load it into our list box.
Now for our last function, the double click event of the list box. In this function, we want to dynamically call the correct object when the user double clicks on it. Since we have the interface as our contract, it is very simple to convert the returned object form the list box into an object of our interface and run the correct subroutine.
As you can see, creating a plug-in architecture in .NET is much easier than it used to be in VB6. Reflection allows you to create a robust dynamic application that your end users will appreciate. It can also allow you to control what end functionality the user gets and allow for easier partial patching of your system when you find bugs in specific plug-ins. In a later article we will examine how to read all information from an assembly in .NET.
Advertisement
Get .NET Code Here!
GetDotNetCode offers inexpensive, well tested, quality and royalty free .NET source code. Our packages are VS.NET projects, well commented and informative. Run the demo, study the code, save time, learn, and be more productive!
Click here for our FREE code offering.
by Mike McIntyre
Most experienced Windows users know how to use the standard wild card characters ( ? and * ) to search for file(s) on their computer. For example *.TXT would be used to find all the files with a file extension of TXT.
A .NET application can programatically scan a directory for files using the standard wild cards too. Here is an example:
' Declare a variable of type FileInfo named aFileInfo.
Dim aFileInfo As System.IO.FileInfo
' Declare a variable of type FileInfo Array named FileInfos.
Dim fileInfos() As System.IO.FileInfo
' Declare a variable of type DirectoryInfo named aDirectoryInfo.
Dim aDirectoryInfo As System.IO.DirectoryInfo
' Use the New constructor to create a DirectoryInfo object
' passing in the path to the C drive.
' Assign the result to the aDirectoryInfo variable.
aDirectoryInfo = New System.IO.DirectoryInfo("C:\")
' Call GetFiles function of the DirectoryInfo object
' passing in some standard wild card characters.
' Assign the result to the fileInfos array variable.
fileInfos = aDirectoryInfo.GetFiles("*.TXT")
' Display the names of the files found.
For Each aFileInfo In fileInfos
Console.WriteLine(aFileInfo.Name)
Next
RESULT:
BOOTLOG.TXT
DemoAttributes.txt
Advertisement
|