Get Trimmed List Of Documents From Document Library (Professional Edition) - dotnetnuke

So I'm building a module where I have to add commenting ability to the built-in Document library feature. I'm trying to find where I pull the documents from. I also want the list security-trimmed. I'm really hoping there's an API and I don't have to build a manual solution that breaks on an update of the document library...
Any help on where to get this information?

You may be able to use the DNN File Picker control, or re-purpose some of it's logic.
The source code available on Codeplex has examples of retrieving folders for a user and an example of retrieving files for a folder (for a user):
http://dotnetnuke.codeplex.com/SourceControl/changeset/view/58672#612642
Private Sub LoadFolders()
cboFolders.Items.Clear()
'Add Personal Folder
If UsePersonalFolder Then
Dim userFolder As String = FileSystemUtils.GetUserFolderPath(UserController.GetCurrentUserInfo().UserID)
Dim userFolderItem As ListItem = cboFolders.Items.FindByValue(userFolder)
If userFolderItem IsNot Nothing Then
userFolderItem.Text = Utilities.GetLocalizedString("MyFolder")
Else
'Add Dummy Folder
cboFolders.Items.Add(New ListItem(Utilities.GetLocalizedString("MyFolder"), userFolder))
End If
Else
Dim folders As ArrayList = FileSystemUtils.GetFoldersByUser(PortalId, ShowSecure, ShowDatabase, Permissions)
For Each folder As FolderInfo In folders
Dim folderItem As New ListItem
If folder.FolderPath = Null.NullString Then
folderItem.Text = Utilities.GetLocalizedString("PortalRoot")
Else
folderItem.Text = folder.DisplayPath
End If
folderItem.Value = folder.FolderPath
cboFolders.Items.Add(folderItem)
Next
End If
End Sub
and
Private Function GetFileList(ByVal NoneSpecified As Boolean, ByVal Folder As String) As ArrayList
Dim fileList As ArrayList
If IsHost Then
fileList = Globals.GetFileList(Null.NullInteger, FileFilter, NoneSpecified, cboFolders.SelectedItem.Value)
Else
fileList = Globals.GetFileList(PortalId, FileFilter, NoneSpecified, cboFolders.SelectedItem.Value)
End If
Return fileList
End Function

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.

Treeview items don't expand

I'm developing a WPF application for my company, and everything needs to look the same way corresponding to our company's look. Therefore I have to make a custom folder explorer, which will feature a treeview of the current directory.
In order to make it easier, I've made the following class, which is basically a TreeViewItem that stores a DirectoryInfo and automaticely browses subfolders when expanded (not to browse everything at once and make the software faster). Here is my code :
Private Class TreeViewPlus
Inherits TreeViewItem
Public dir As IO.DirectoryInfo
Public Sub New()
End Sub
Public Sub New(dir As DirectoryInfo)
Me.dir = dir
Try
If Not dir.EnumerateDirectories Is Nothing Then 'If there are subdirectories, I add an empty item to enable the expansion
Me.Items.Add(New TreeViewPlus)
End If
Catch ex As Exception
End Try
End Sub
Private Sub TreeViewPlus_Expanded(sender As Object, e As RoutedEventArgs) Handles Me.Expanded
Me.Items.Clear()
Try
For Each folder In dir.EnumerateDirectories()
Dim item As TreeViewPlus = New TreeViewPlus(folder)
item.Name = Text.RegularExpressions.Regex.Replace(folder.FullName, "[^a-zA-Z0-9]", "")
item.Header = folder.Name
Me.Items.Add(item)
Next
Catch ex As Exception
End Try
End Sub
End Class
And here is the code where I initialize the first directories: (TRV_Arbre is the name of my TreeView)
Sub New()
...
For Each Drive As IO.DriveInfo In IO.DriveInfo.GetDrives
Dim item As TreeViewPlus = New TreeViewPlus(Drive.RootDirectory)
item.Header = Drive.Name
TRV_Arbre.Items.Add(item)
Next
...
End Sub
The Issue I've got is that the first level of items correctly expand, but not the following ones.
See here : https://youtu.be/E6BJbKal5Sk
I've already debugged my code a little, and it correctly creates the different Items.
Can anyone help me for this ? Thanks in advance.
There is a simple way to solve this problem and that is to Override the OnExpanded Sub on the Base TreeViewItem class instead of implementing your own Expanded method. Then in the end you execute MyBase.OnExpanded(e) method which seems to contain the correct update events to send out to whomever listens. In this case your TreeView.
Protected Overrides Sub OnExpanded(e As RoutedEventArgs)
Me.Items.Clear()
Try
For Each folder In dir.EnumerateDirectories()
Dim item As TreeViewPlus = New TreeViewPlus(folder)
item.Name = Text.RegularExpressions.Regex.Replace(folder.FullName, "[^a-zA-Z0-9]", "")
item.Header = folder.Name
Me.Items.Add(item)
Next
Catch ex As Exception
End Try
MyBase.OnExpanded(e)
End Sub

Exception with sqlite database "no such table"

First of all I´m developing a database with autosuggest box. I´ve created a database with DB Browser and imported data. I was reading documentation in C# how connect database and retrieve data. The issue is show up an exception error:
enter image description here
I´ve connected the database in properties with content option. I paste the code:
Public NotInheritable Class METARTAF
Inherits Page
Dim dbpath As String = Path.Combine(ApplicationData.Current.LocalFolder.Path, "airportsdb.sqlite3")
Dim conn As SQLite.Net.SQLiteConnection = New SQLite.Net.SQLiteConnection(New WinRT.SQLitePlatformWinRT(), dbpath)
Dim airportinfo As List(Of String) = Nothing
Public Sub New()
' This call is required by the designer.
InitializeComponent()
End Sub
Private Sub AutoSuggestBox_TextChanged(sender As AutoSuggestBox, args As AutoSuggestBoxTextChangedEventArgs)
Dim datairport As New List(Of String)
Dim retrieve = conn.Table(Of flugzeuginfo)().ToList
If args.Reason = AutoSuggestionBoxTextChangeReason.UserInput Then
If sender.Text.Length > 1 Then
For Each item In retrieve
datairport.Add(item.IATA)
datairport.Add(item.ICAO)
datairport.Add(item.Location)
datairport.Add(item.Airport)
datairport.Add(item.Country)
Next
airportinfo = datairport.Where(Function(x) x.StartsWith(sender.Text)).ToList()
sender.ItemsSource = airportinfo
End If
Else
sender.ItemsSource = "No results..."
End If
End Sub
Private Sub AutoSuggestBox_SuggestionChosen(sender As AutoSuggestBox, args As AutoSuggestBoxSuggestionChosenEventArgs)
Dim selectedItem = args.SelectedItem.ToString()
sender.Text = selectedItem
End Sub
Private Sub AutoSuggestBox_QuerySubmitted(sender As AutoSuggestBox, args As AutoSuggestBoxQuerySubmittedEventArgs)
If args.ChosenSuggestion Is Nothing Then
stationidtxt.Text = args.ChosenSuggestion.ToString
End If
End Sub
Anyone could help about this?
Before you query or insert into a table, you should CREATE it. This tells SQLite what columns you have and suggests datatypes (on other rdbms's you get actual data type enforcement but SQLite does not do that). If this is your problem, you will want to spend some time with the SQLite documentation on data types and the ability to hook them into your application.
On the other hand, as you seem to be trying to retrieve data, this suggess one of two things is wrong. Either you care connecting to the wrong db (in which case SQLite will usually helpfully create an empty db for you!) or else you are specifying the wrong table.

How to have a global Dictionary in VB.NET/WPF application to save data from different windows?

I am new to VB.NET and WPF.
I am building a "Questionnaire" app. Users will be presented sequentially with different questions/tasks (windows). After they respond on each question/task and press a "submit" button a new window will open with a new question/task, and previous window will close. After each question, when the button is pressed, I need to store data to some global object. After all questions are answered the data of this object should be written out to the output file.
I figured out that Dictionary will be the best to store the results after each window.
I am not sure how, where to create this global Dictionary and how to access it. Should I use View Model? If yes, can you give an example? Or, should it be just a simple class with shared property? (something like this)
EDIT 2: I tried many different ways recommended online
GlobalModule:
Module GlobalModule
Public Foo As String
End Module
GlobalVariables:
Public Class GlobalVariables
Public Shared UserName As String = "Tim Johnson"
Public Shared UserAge As Integer = 39
End Class
Global properties:
Public Class Globals
Public Shared Property One As String
Get
Return TryCast(Application.Current.Properties("One"), String)
End Get
Set(ByVal value As String)
Application.Current.Properties("One") = value
End Set
End Property
Public Shared Property Two As Integer
Get
Return Convert.ToInt32(Application.Current.Properties("Two"))
End Get
Set(ByVal value As Integer)
Application.Current.Properties("Two") = value
End Set
End Property
End Class
Here is where I save the data to global variables/properties in the first window. I need to store data in this subroutine before closing an old window and opening a new window. I use MessageBox just for testing.
Private Sub btnEnter_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnEnter.Click
Dim instructionWindow As InstructionsWindow
instructionWindow = New InstructionsWindow()
Application.Current.Properties("number") = textBoxValue.Text
Globals.One = "2"
Globals.Two = 3
MessageBox.Show("GlobalVariables: UserName=" & GlobalVariables.UserName & " UserAge=" & GlobalVariables.UserAge)
GlobalVariables.UserName = "Viktor"
GlobalVariables.UserAge = 34
GlobalModule.Foo = "Test Foo"
'testing if it saved tha value
'MessageBox.Show(Application.Current.Properties("number"))
Application.Current.MainWindow.Close()
instructionWindow.ShowDialog()
End Sub
Next subroutine is where I am trying to retrieve the value from global Properties/variables in the second window, but message boxes come out empty. There might also the case that I am assigning values in a wrong way, or not reading them in a right way (casting?) :
Private Sub FlowDocReader_Initialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles FlowDocReader.Initialized
' Get a reference to the Application base class instance.
Dim currentApplication As Application = Application.Current
MessageBox.Show(currentApplication.Properties("number"))
MessageBox.Show("One = " & Globals.One & " Two = " & Globals.Two)
MessageBox.Show("GlobalVariables: UserName=" & GlobalVariables.UserName & " UserAge=" & GlobalVariables.UserAge)
MessageBox.Show("GlobalModule.Foo = " & GlobalModule.Foo)
Dim filename As String = My.Computer.FileSystem.CurrentDirectory & "\instructions.txt"
Dim paragraph As Paragraph = New Paragraph()
paragraph.Inlines.Add(System.IO.File.ReadAllText(filename))
Dim document As FlowDocument = New FlowDocument(paragraph)
FlowDocReader.Document = document
End Sub
Thanks.
You can make public Dictionary property for form and put your dictionry to this property or make constructor with Dictionary argument.
You already have this dictionary Application.Properties
Look here, please.
First, you can define a dictionary (list of lists) as follows at the beginning of a form or in a module
Dim dic As New Dictionary(Of String, List(Of String))
As the user completes questions on a form, write the partucular form number and query results to a single record in the dic before going to the next form (place this code into the "Next" button):
'Assume q1response=3, q2response=4,..., qpresponse="text", etc.
Dim myValues As New List(Of String)
myValues.Add(formname)
myValues.Add(q1response)
myValues.Add(q2response)
.
.
myValues.Add(qpresponse)
dic.Add(username, myValues)
When a user is done, there will be multiple records in the dictionary, each of which starts with their name and is followed by question responses. You can loop through multiple dictionary records, where each record is for a user using the following:
For Each DictionaryEntry In dic 'this loops through dic entries
Dim str As List(Of String) = DictionaryEntry.Value
'here you can do whatever you want with results while you read through dic records
'username will be = str(0)
'formname will be str(1)
'q1 response on "formname" will be str(2)
'q2 response on "formname" will be str(3)
'q3 response on "formname" will be str(4)
...
Next
The trick is that there will be multiple dictionary records with results for one user, where record one can have results like "John Doe,page1,q1,q2,q3" and record 2 will be "John Doe,page2,q4,q5,q6." Specifically, the "str" in the above loop will be an array of string data containing all the items within each dictionary record, that is, in str(0), str(1), str(2),... This is the information you need to work with or move, save, analyze, etc.
You can always put all the code I provided in a class (which will be independent of any form) and dimension the sic is a Sub New in this class, with the updating .Add values lines in their own sub in this same class). Then just Dim Updater As New MyNewClassName. Call the Updater in each continue button using Call Updater.SubNameWithAddValues(q1,q2,...qp). It won't matter where you are in your program since you using a specific class. The one thing I noticed with my code is that you can only use the line that adds the "key" or the username once, so use it after the last query -so put it in a Sub Finished in your new class and call as Call Updater.Finished(username,q30,q31,last)

VBS - Create object and pass that through functions and subs?

I'm trying something out. I've got this system where a bunch of scripts are triggered at certain event handlers. This is used during the creation of Users in Active Directory.
So, what I think I need is a function that basically collects the properties of the user being processed into - hopefully, an object. And then returning that object and using it in other functions and subs. So that I can perhaps reach the properties I want using only "myObject.firstname" and that's it.
How can I create an object, create and set values in it and returning the entire object? Is this possible in VBS?
Edit: What would be best if I could create an Object that holds these properties and just being able to access them whenever I need to.
I'm basically after something like this:
Public Sub Main()
Set userStream = New objUser
msgbox objUser.firstname
msgbox objUser.lastname
msgbox objUser.username
End Sub
Edit: To explain furter, I have this library script which is called 'libGetUserProperties'
It's in this I want the function and Class. Then I just import this library script in the actual script that is run at runtime. Looks like this:
libGetUserProperties:
Public Function getobjUser(ByRef Request, ByVal From)
Dim thisUserObject
Set thisUserObject = New objUser
'If type = 0, data comes from AD
If From = 0 Then
thisUserObject.firstname = "some string"
thisUserObject.lastname = "some string"
End If
'If type = 1, data comes from Request stream
If From = 1 Then
thisUserObject.firstname = "some string"
thisUserObject.lastname = "some string"
End If
Set getobjUser = thisUserObject
End Function
Class objUser
Public firstname
Public lastname
Public username
End Class'
This is what the actual runtime Script looks like:
Dim libGetUserProperties
Set libGetUserProperties = ScriptLib.Load("Script Modules/Library Scripts/libGetUserProperties")
Sub onPreCreate(Request)
Dim userStream
Set userStream = New objUser
'Do whatever with objUser which contains all of the properties I'm after
End Sub
That’s not possible using VBScript, unless you want to dynamically generate the code for a class, including the properties, save that to file, and then execute that file as a script.
This is so much easier to do using JScript. Since Windows Scripting can handle JScript as well as VBScript, I’d recommend going that way.
If you definitely need VBScript, the best you can go for is a Scripting.Dictionary that would contain the properties as keys:
Dim dicUser
dicUser = CreateObject("Scripting.Dictionary")
dicUser("FirstName") = objUser.FirstName
which would allow you to access the first name as follows:
dicUser("FirstName")
Update
If you want to write a function which creates a dictionary and returns that, this is how to do it in VBScript:
Function RememberTheUser(Request)
Dim dicResult
Set dicResult = CreateObject("Scripting.Dictionary")
dicResult("FirstName") = Request.GetTheFirstName
Set RememberTheUser = dicResult
End Function
Which can then be assigned to some other variable:
Dim dicUser ' in the main section of the script, this means it's a global variable
Sub onPreCreate(Request)
' ...
Set dicUser = RememberTheUser(Request)
' ...
End Sub
Sub onSomethingLater()
WScript.Echo dicUser("FirstName") ' It's still accessible here
End Sub
In JScript, it’s a lot easier: just create a new object, and tack on new properties.
function readObject(dataSource) {
var result = {};
result.source = dataSource;
result.firstName = dataSource.firstName;
result['lastName'] = dataSource.FunctionThatGetsLastName();
}
Note that in JScript, object properties can be accessed using the object.property notation, but also through the object['property'] notation, which is very useful when you have dynamically-named properties. ('property' in the second notation is a string, and can be replaced by any expression that returns a string).
Keeping with VBScript, a disconnected recordset would work as well and is possibly faster than a dictionary; see here for an example.

Resources