Redirect a picture to a direct location - wpf

Im using WPF and VB.net and in order to use a picture (source) for an image you need the file to be in the folder of the application, so the source of stack.png would be stack.png.
But I want to use C:/APictureLocation/stack.png. I think Releative file name maybe? I honestly do not know how to ask a question without explaining. Sorry.
So I can do:
image.source = "C:\APictureLocation\stack.png"
instead of
image.source = "stack.png"
Thanks for you help!
Do not vote down without giving me pointers. Doesn't help the community.
My answer!
Private Sub BrowseButton_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)
Dim dialog As New OpenFileDialog()
dialog.InitialDirectory = "C:\"
dialog.ShowDialog()
picbox.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri(dialog.FileName, UriKind.Absolute))
End Sub

I believe I have the solution to your problem (or what I think your asking)...
Let's say your image source folder is 'C:\Images\ProgramImages'
(notice how I have used a '\' not a '/' in my path...)
Firstly, create a new form called 'ImageBrowser'. Then, add a ListBox control and name it 'ImageBrowserLB'. After this, double click on the ImageBrowser form so it takes you to the code editor. In the auto-generated sub, type the following:
For Each F As File In System.IO.Directory.GetFiles("C:\Images\ProgramImages\")
If Path.Extension(F) = ".png" Then
ImageBrowserLB.Items.Add(Path.GetFileName(F))
End If
Next
When that form loads, it will add all the files with a PNG extension in the directory I specified. I'm sure you can take this code and manipulate it to do what you would like (which isn't very clear in your question!).
Hope this helped,
Rodit

Related

Compare column of a table with images in a folder on the server - VB.NET / SQL Server

In my Product Registration form, I have a Photo button to show the product photo in a pictubox1.
When the user clicks the photo button, the code will make a comparison between the prdCod column of the Products table and the filename of the image in the Photo folder on the server, and when found, it will show the corresponding image in picturebox1.
Photo button, execute the commands below:
Private Sub btnPhoto_Click(sender As Object, e As EventArgs) Handles btnPhoto.Click
Dim IdProduto As String = prdCod ** column in Products table that will be used for the search image in the Photos folder
If File.Exists("\\server\cmg\projects\Photos" & IdProduto) Then ** Search the image from the Photos folder on the server
PictureBox1.Image = Image.FromFile("\\server\cmg\projects\Photos" & IdProduto)
End If
End Sub
On the line
If File.Exists("\\server\cmg\projects\Photos" & IdProduto)
I have 2 problems:
The image's filetype is being read in the comparison with the prdCod and I need to compare only the filename of the image for it to work;
When the image's filename has leading zeros, the comparison doesn't work either.
Note #1: these images will not be saved in the Products table, they will already be in the Photos folder on the server and are only for being shown in picturebox1.
Note #2: the filenames of the images in the Photos folder will always be numbers and will never be repeated, ex.:\
1.png, 2.png, 3.bmp, 4.jpg, 5.bmp, 6.jpeg...
How do I compare only the image filename from the Photos folder, without the filetype, and also ignoring the leading zeros?
You can use the GetFiles method and use a wildcard for the extension.
Private Sub AddImageIfExists(idProduto As String)
Dim folder As New DirectoryInfo("\\server\cmg\projects\Photos")
If folder.Exists Then
Dim file = folder.GetFiles($"{idProduto}.*").FirstOrDefault
If file IsNot Nothing Then
PictureBox1.Image = Image.FromFile(file.FullName)
End If
End If
End Sub
That will add the photo if present.
To call the method:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim IdProduto As String = prdCod
AddImageIfExists(IdProduto)
End Sub
There is no easy solution to that. You basically have to iterate through all files in the folder, use e.g. Path.GetFileNameWithoutExtension and remove leading zeros from that, before you do your comparison.
A better way ofc. would be to redesign the workflow and store the corresponding real filename (or even the fully qualified filename) along with the product code.

Insert a picture into a Access table with a SQL Server Backend

I need to insert an image into a MS Access form (not link it, as it is a licence, and it needs to be encrypted and protected). I have a MS Access front end and a SQL Server backend. This is the code for the insert
Private Sub AddLicence1Picture_Click()
Dim f As Object
Set f = Application.FileDialog(1)
f.allowmultiselect = False
If (f.Show = True) Then
Me![LicencePicture1].Picture = f.selecteditems(1)
End If
End Sub
I have a table that holds all the other data, and a column called LicencePicture1, and the data type is set to IMAGE and I have also tried setting it to VARBINARY(MAX). Can anyone please point me in the right direction as to what in doing wrong?
Well, one step at a time (encryption can be part 2).
So, for some reason a varbinary(max) column does not work with the standard odbc driver.
However, if you create sql server image column, then it can/will work.
The first step? Use the NEW image control - NOT the oleDB one from the ribbon.
So, choose this one:
Next up, you find that if you BIND that image control to the database column (linked table to sql server), it will not work.
However, you can still shove the image file (as raw binary) into that column, and save the current record.
And you can also display.
So, you can navigate to the given record, then say have a button to browse to the given file - similar to what you have.
So, we have this:
Private Sub cmdFile_Click()
Dim f As FileDialog
Set f = Application.FileDialog(msoFileDialogFilePicker)
f.Show
If f.SelectedItems.Count > 0 Then
Me.txtFile = f.SelectedItems(1)
End If
End Sub
Ok, so that puts the picture path into a un-bound text box.
We have this so far:
Now, note the save to db button. The code for that button looks like this:
Private Sub cmdSaveToDB_Click()
' save current record
If Me.Dirty Then Me.Dirty = False
Dim MyImage() As Byte
MyImage = GetFileBytes(Me.txtFile)
Me!ImageB = MyImage
Me.Dirty = False
End Sub
And we also need this binary file read routine - it uses the path name in the text box
Public Function GetFileBytes(ByVal path As String) As Byte()
Dim lngFileNum As Long
Dim bytRtnVal() As Byte
lngFileNum = FreeFile
If LenB(Dir(path)) Then ''// Does file exist?
Open path For Binary Access Read As lngFileNum
ReDim bytRtnVal(LOF(lngFileNum) - 1&) As Byte
Get lngFileNum, , bytRtnVal
Close lngFileNum
Else
Err.Raise 53
End If
GetFileBytes = bytRtnVal
Erase bytRtnVal
End Function
That's it.
As noted, the only issue is that we can't bind the picture box directly to the forms data source.
but, you can do this:
So, in above, dropped in a button to display the picture.
It looks like this:
Private Sub cmdShowFromDB_Click()
Me.Image1.PictureData = Me.Recordset!ImageB
End Sub
So, the results now look like this:
If you only load the form to one reocrd then put the code to "set" the image in the forms on-load event.
However, if you allow navagation, then you have to use the on-current to automatic display the image.
But, at least now with the new image control (2010 I think??), then you don't need a lot of special code.
so above saves the binary picture (raw) to sql server:

VB: Changing shortcut properites

I have a code, which task would be changing .url or .lnk (shortcuts) properties, but it does not seem to do anything.
Imports System.IO
Imports Shell32
Module Module1
Sub Main()
'References Microsoft Shell Controls and Automation.
'http://msdn.microsoft.com/en-us/library/bb776890%28v=VS.85%29.aspx
End Sub
Public Sub Change_Shortcut()
Dim shell As Shell32.Shell
Dim folder As Shell32.Folder
Dim folderItem As Shell32.FolderItem
Dim shortcut As Shell32.ShellLinkObject
shell = New Shell32.Shell
folder = shell.NameSpace("C:\Users\GrzegoP\Desktop\xxx") 'Shortcut path
If Not folder Is Nothing Then
folderItem = folder.ParseName("o2.url") 'Shortcut name
If Not folderItem Is Nothing Then
shortcut = folderItem.GetLink
If Not shortcut Is Nothing Then
shortcut.Path = "www.o2.ie" 'new shortcut address
shortcut.Save()
MsgBox("Shortcut changed")
Else
MsgBox("Shortcut link within file not found")
End If
Else
MsgBox("Shortcut file not found")
End If
Else
MsgBox("Desktop folder not found")
End If
End Sub
End Module
Can anyone give me some advice where am I going wrong?
Thanks.
It's noted here that you cannot create a URL shortcut that way:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb776891%28v=vs.85%29.aspx
You should instead simply create a xxx.url file on the desktop, writing the following lines of text inside of it:
[InternetShortcut]
URL=http://www.o2.ie
Windows will turn that into a web-site shortcut.
From my understanding, it sounds like nothing is getting executed. Try putting a breakpoint at the beginning of the sub to see if it even gets called. If it does not, then make sure you're able to properly connect the Change_Shortcut() so it gets called appropriately.
Once you set up your breakpoint, you should be able to walk through the code and see where you end up to ensure it all works as expected.
A simple solution to my problem...
in the line: shortcut.Path = "www.o2.ie"
I forgot to put http:// in front of the address.

strange problem with reflection and static method

Visual Studio 2008 - framework 3.5 - Visual Basic
Hi!
I have a problem with a static method invoked by reflection.
On the loading of my win-wpf I create a copy of "A4Library.dll" with the name "_temp.dll", in the same directory of the original.
Then, on a button-click event, I invoke a static method on the _temp.dll in this way:
Dim AssemblyFileName As String = Directory.GetCurrentDirectory() & "\_temp.dll"
Dim oAssembly As Assembly = Assembly.LoadFrom(AssemblyFileName)
Dim TypeName As String = "MyLibrary.MyService"
Dim t As Type = oAssembly.GetType(TypeName)
Dim mi As MethodInfo = t.GetMethod("MyMethod", BindingFlags.Static AndAlso BindingFlags.Public)
Dim bResponse As Boolean = mi.Invoke(Nothing, New Object() {MyPar1, MyPar2})
But this works well only if I the .exe file is not in the same directory of the .dll files, otherwise I obtain this error (translated):
InnerException {"Cast impossible of [A]MyType on [B]MyType. The type A is originated from ... in the context 'Default' in the position 'F:\MyPath\A4Library.dll'. The type B is originated from ... in the context 'LoadFrom' in the position 'F:\MyPath_temp.dll'."}
It's strange: it seems to be a conflict with the same method in the original .dll, but I can't undertend why it looks at the original and not at the copy. If the .exe file relative to the principal assembly is placed in another directory, all runs well.
I neet to have the .exe in the same folder of the .dll, how can I solve the problem?
Thank you!
Pileggi
Why create a copy of assembly before executing static method? If creating a copy is needed, load that assembly in another AppDomain and execute the method in there.

ADO.NET: Need help to understand the basics of 'Dataset'

As context, I am new to ADO.NET and have been using 'Programming ADO.NET 2.0' by David Sceppa to help build my knowledge.
I have been trying to understand the Dataset object but think I may have completely misunderstood the point and am looking for guidance.
As an example, I have built a really simple Form with a combobox with an aim of filling the combobox with the names of people in a database ("MyDatabase"). The following code works fine for me:
Private Sub frmEmployee_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim strConn, strSQL As String
strConn = "Data Source=.\SQLExpress;Initial Catalog=MyDatabase;Integrated Security=True;"
strSQL = "SELECT LastName, FirstName FROM EmployeeTable"
Dim da As New SqlDataAdapter(strSQL, strConn)
Dim ds As New DataSet()
da.Fill(ds, "AllEmployeesList")
For i As Integer = 0 To ds.Tables("AllEmployeesList").Rows.Count - 1
Dim row As DataRow = ds.Tables("AllEmployeesList").Rows(i)
cbAllEmployeesList.Items.Add(row("LastName") & ", " & row("FirstName"))
Next
End Sub
Now suppose I have a button on my Form ('GetAge') which is designed to retrieve the age of the employee selected in the combobox from the dataset "AllEmployeesList" and display in a TextBox on the same Form.
The bit I really don't understand is how I can interact with the original dataset that I have created to get the age? It seems to me that the dataset is only in memory during the Load event? If my dataset persists beyond the Load event then where can I find it?
My understanding is that a dataset object is an offline cache of data and has no links to the underlying database.This is useful as it allows you to manipulate the data without keeping a connection open and later on you can submit any changes in the Dataset back to the original database. So once I have built my dataset in the Load event how can I then further interact with it?
I suspect there is a large error in my understanding of what a Dataset object is. Can anybody set me straight?
Thanks to anybody who can help
Alex
A data set can hold multiple data tables, so if you fill that same dataset that already has the "AllEmployeesList" datatable filled, you can fill another datatable with the age under another table name. Picture a dataset as an in-memory database.
You can store the dataset in the datasource of the datagrid view, or make it a form level variable so you can interact with it without casting anytime.
Another part of datasets to be aware of is you can make a design-time dataset so things are more type-safe and explicit.
You seem to have a good grasp on the concept and reason of the DataSet. Your question is really more about managing state than the ins and outs of a DataSet.
You never stated if you are using WebForms, WinForms, or something else. If you're using WinForms, promote the DataSet to be a member variable of the form. It'll stay in memory as long as the form is open.
If you're using WebForms, then this becomes much more complex. This is a good overview to get you started.
Unless your application needs to operate in a disconnected mode, it's not strictly necessary nor always a good idea to cache database data on the client. In this case, you're extracting the age data for all employees without knowing whether you'll ever need it for any of them.
I would just pull the first and last name data (probably using SqlCommand.ExecuteReader) to populate the list box, and then make a separate call to the database to get the age if the user clicks the button. I posted an example of something similar using SqlCommand.ExecuteScalar on your other question.
When a Function or Sub has finished executing, all the variables you declared with the Dim statement will be gone. If you want a variable to exist as long as your form exists then declare a variable outside your Sub/Function:
Public Class frmEmployee
Private dsEmployeeList As DataSet
Private Sub frmEmployee_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
...
dsEmployeeList = New DataSet()
da.Fill(dsEmployeeList, "AllEmployeesList")
...
End Sub
Private Sub GetAge_Click(sender As Object, e As EventArgs) Handles GetAge.Click
Dim iRowIndex As Integer
iRowIndex = cbAllEmployeesList.SelectedIndex 'In this case the rownumber is the same as the index of the selected item in the combobox
'Check to see if an item from the combobox has been selected
If iRowIndex >= 0 Then
txtEmployeeAge.Text = dsEmployeeList.Tables("AllEmployeesList").Rows(iRowIndex).Item("Age").ToString()
End If
End Sub
This code might work but it's not a recommended solution. Like the previous poster said: only get the data you want, when you need it.
You should bind the DataGrid to the DataSet. When reqd you can retrieve the DataSet back from the DataGrid.DataSource and cast it to a DataSet.
Edit: Added sample code
DataSet ds = new DataSet();
// Code to populate DataSet from your DB
...
...
Assign ds to the datasource of data grid
this.dataGridView1.DataSource = ds;
To retrieve the dataset use the code below
DataSet retrievedFromGrid = (DataSet)this.dataGridView1.DataSource;
However, if you need to perform operations on this DataSet a number of times and memory is not an issue, I would suggest you store it in a class variable to avoid the overhead of casting in a DataSet object from the DataGrid again and again.

Resources