I'm having some evils trying to get my GridView control to behave. I have the below code, which successfully displays all the files in the directory. However I require two changes, both of which I am struggling with:
a) Currently the URL you get when clicking on the URL field is
http://localhost/LBSExplorer/SharedUser.csv (ie my home directory with the filename).
What I require is that the 'Display Text' be the filename only, and the URL be my desired text followed by the filename eg:
http://mystuff/page.aspx?FileID=SharedUser.csv
b) I want only to see the files that start with a certain prefix eg "Pay". I can do that with something like:
string[] filelist = Directory.GetFiles((#"C:\MF\Data\","Pay*.*");
but this doesn't like to bind to my Gridview!
I'd appreciate your help!
Mark
const string DocumentFolderPhysicalPath = (#"C:\MF\Data\");
const string DocumentFolderUrl = (#"C:\MF\Data\"); //"http://localhost/virtualfoldernameyouexposed/"; ; // now it is hardcoded but you could retreive it automatically
HyperLinkField hyperLinkField = new HyperLinkField();
hyperLinkField.DataTextField = "Name";
hyperLinkField.DataNavigateUrlFields = new string[] { "Name" };
//Would like this to work!
//HyperLinkField hyperLinkField2 = new HyperLinkField();
//hyperLinkField2.DataTextField = "Destination";
//hyperLinkField2.DataNavigateUrlFields = new string[] { (#"C:\MF\Data\") + "Name" };
GridView1.DataSource = GetDocuments(DocumentFolderPhysicalPath);
GridView1.Columns.Add(hyperLinkField);
GridView1.DataBind();
private System.IO.FileInfo[] GetDocuments(string physicalPath)
{
System.IO.DirectoryInfo directory =
new System.IO.DirectoryInfo(physicalPath);
if (directory.Exists)
{
return directory.GetFiles();
}
else
{
throw new System.IO.DirectoryNotFoundException(physicalPath);
}
}
What you are looking for is the DataNavigateUrlFormatString property.
hyperLinkField.DataNavigateUrlFormatString = "http://mystuff/page.aspx?FileID={0}";
The {0} here is replaced with your DataNavigateUrlFields value.
Related
I have too many files on ftp server which I want to display in data gridview without saving or downloading and sort by date. These files are .qrt but I can open them in excel or notepad.
I did that but from sql db but never worked with ftp.
These files have names with dates.
I'm using asp.net web forms in C#.
How can I do this?
This as noted is quite easy. But, you don't mention if you have a bunch of folders that you want to display, or just files from one FTP folder?
As noted, if you have a bunch of folders, then VERY easy to use a tree view to display this hierarchy type setup. However, for one folder? Sure, a GridView is a great choice.
You can say use this:
our markup is thus this:
<asp:GridView ID="GridView1" runat="server"
CssClass="table" Width="20%"></asp:GridView>
Ok, and our code is this:
using System.Net;
using System.IO;
So, for page load, we have this:
const string UserId = "User Name here";
const string Password = "Password here";
const string fRoot = "ftp://ftp.mycoolwebsite.com/test";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
DataTable MyFiles = new DataTable();
MyFiles.Columns.Add("File", typeof(string));
List<string> fList = GetFtpFiles();
foreach (string sFile in fList)
{
DataRow OneRow = MyFiles.NewRow();
OneRow["File"] = sFile;
MyFiles.Rows.Add(OneRow);
}
GridView1.DataSource = MyFiles;
GridView1.DataBind();
}
List<string> GetFtpFiles()
{
FtpWebRequest ftpR = (FtpWebRequest)WebRequest.Create(fRoot);
ftpR.Credentials = new NetworkCredential(UserId, Password);
ftpR.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = ftpR.GetResponse() as FtpWebResponse;
StreamReader sread = new StreamReader(response.GetResponseStream());
List<string> myDir = new List<string>();
string oneLine = sread.ReadLine();
while (!string.IsNullOrEmpty(oneLine))
{
myDir.Add(oneLine);
oneLine = sread.ReadLine();
}
sread.Close();
return myDir;
}
And out output is now this:
Now, if we want the file size? that's a problem, since in theory ONCE we have the file list, we could cook up code to "request" each file size - that's a pain, but WORSE is a lot of requests. The other way, is we can change this:
ftpR.Method = WebRequestMethods.Ftp.ListDirectory;
to:
ftpR.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
The above will return file information VERY much like an old style DOS file listing.
When we run above with above, we now get this:
So, if we want to sort say by file name, we have to parse out the file name, and date. This is not too hard. As noted, the other way is to "request" the file size an date for each file - but that is extra code, but WORSE is a LOT of hits to the ftp server.
And the style of the file listings are not consistent from web servers (might be windows, or linux), but we COULD parse out the above into columns - and then we can sort by date, or file name.
Parsing? Gee, this works:
void LoadGrid()
{
DataTable MyFiles = new DataTable();
MyFiles.Columns.Add("Date", typeof(DateTime));
MyFiles.Columns.Add("Size", typeof(int));
MyFiles.Columns.Add("File", typeof(string));
List<string> fList = GetFtpFiles();
foreach (string s in fList)
{
DataRow OneRow = MyFiles.NewRow();
string sRow = s;
while (sRow.Contains(" "))
sRow = sRow.Replace(" ", " ");
sRow = sRow.Replace(" ", ",");
string[] scols = sRow.Split(',');
OneRow["Size"] = scols[4];
OneRow["File"] = scols[8];
OneRow["Date"] = scols[7] + "-" + scols[6] + "-" + scols[5];
MyFiles.Rows.Add(OneRow);
}
GridView1.DataSource = MyFiles;
GridView1.DataBind();
}
And now we get this:
We need to formt that ate in the grid - but at least now, with a table, you can sort that table by date, or filename before you bind it, say like this:
MyFiles.DefaultView.Sort = "File";
GridView1.DataSource = MyFiles;
GridView1.DataBind();
And you can/could sort by date also - since we defined date column as datetime.
I write codes to receive the path of a text file and store it in a string variable that I declare in public.
Then I want to know if the file exists or not by using
System.IO.File.Exists(pathoffile)
But it always returns false even though there is a file.
And then when I try to add the string path directly like this
public string propertyfile = #"C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt"
The function
System.IO.File.Exists(pathoffile)
return true
I already check the receive path(string) that I read from the text file. By cutting off "\n" and "\r" and using trim() too.But it still returns false.
Have I missed something? What difference between these two?. I'm too new to this c#. I'm very bad at this sorry in advance.
Here are my codes
public string pathfromread, partnumber, pathfile, portname, partnofromserial,propertypathfile; //Declare Variables
public string propertyfile = #"C:\Users\PFA Wongsawat\Desktop\Properties.txt";
public string pathoffile ;
public string backuppath ;
public string pdffolderpath ;
private void propertyget()
{
if (File.Exists(propertyfile))
{
StreamReader readpropertyfile = new StreamReader(propertyfile);
string readproperty;
while ((readproperty = readpropertyfile.ReadLine()) != null)
{
string[] propertyfromread = readproperty.Trim().Split('=');
if (propertyfromread.GetValue(0).ToString() == "pathoffile")
{
pathoffile = propertyfromread.GetValue(1).ToString();
pathoffile = pathoffile.Replace("\n", "").Replace("\r", "");
MessageBox.Show(pathoffile, "path file");
}
else if ((propertyfromread.GetValue(0).ToString() == "backuppath"))
{
backuppath = propertyfromread.GetValue(1).ToString();
backuppath = backuppath.Replace("\n", "").Replace("\r", "");
MessageBox.Show(backuppath);
}
else if ((propertyfromread.GetValue(0).ToString() == "pdffolderpath"))
{
pdffolderpath = propertyfromread.GetValue(1).ToString();
pdffolderpath = pdffolderpath.Replace("\n", "").Replace("\r", "");
MessageBox.Show(pdffolderpath);
}
else if ((propertyfromread.GetValue(0).ToString() == "portname"))
{
portname = propertyfromread.GetValue(1).ToString();
portname = portname.Replace("\n", "").Replace("\r", "");
MessageBox.Show(portname);
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
propertyget();
dv = dt.DefaultView; //set dv index count to != 0 to prevent error from null input when click on remove button
if (System.IO.File.Exists(pathoffile))//Check if file exist or not
{
}
else
{
try
{
MessageBox.Show("Database Text File Missing. Please Select New File", "Database Text File Missing", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
OpenFileDialog regispath = new OpenFileDialog();
regispath.Title = "Select Database Text File (part_no_and_path_list.txt)";
regispath.Multiselect = false;
regispath.Filter = "Text file (*.txt)|*.txt";
regispath.RestoreDirectory = true;
regispath.ShowDialog();
pathfile = regispath.FileName;
File.Copy(pathfile, pathoffile);
}
catch
{
And this is my property text file
pathoffile=#"C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt"
backuppath=#"C:\Users\PFA Wongsawat\Documents\part_no_and_path_list.txt"
pdffolderpath=#"C:\Users\PFA Wongsawat\Downloads\"
portname=COM3
In this case the result always a messageBox showing "Database Text File Missing. Please Select New File"
Thank you and sorry for my bad English.
You don't put #" and " in the text file, you only put them in the code because that's how the c# compiler knows they're strings (and knows not to interpret slashes as an escape character)
Just make your text file look like:
pathoffile=C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt
I also recommend you use:
Split(new []{'='}, 2)
This will allow you to use = in your path, by making split return a maximum of 2 split values; any = that are legitimately in the path would be preserved
Actually I recommend you use one of the various built in settings mechanisms that c# has; we haven't needed to read and write our own configuration files for about 25 years
If you really do want to continue rolling your own you can reduce your code massively by using a dictionary
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class Settings{
private Dictionary<string,string> _conf = new Dictionary<string,string>();
public string PathOfFile {
get => _conf["pathoffile"];
}
public void ReadConfig(){
File.ReadAllLines("conf.txt").ToDictionary(
x => x.Split(new[]{'='},2)[0],
x => x.Split(new[]{'='},2)[1]
);
}
}
Yep, it's all you need. Every time you want to add another setting, add another property (like public string PathOfFile), add another love to the file and make sure the string in the property matches the line in the file
In other areas, please read up on c# naming conventions; PublicThingsAreNamedLikeThis, _privateLikeThis, localLikeThis, neverlikethis
Thank you I've already solved this problem
By remove "#" and '""' from path in the property text file like this.
pathoffile=C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt
backuppath=C:\Users\PFA Wongsawat\Documents\part_no_and_path_list.txt
pdffolderpath=C:\Users\PFA Wongsawat\Downloads\
portname=COM3
The reason I can't see this because I debug the program by seeing the result in message box and it not match with the real one. Thank you.
I am having an issue with the Revit API PrintManager properties, in particular with the PrintToFileName property and the error: Invalid fileName.
What is the proper way to declare what you wish for a printed view to be named when printing to pdf?
My Source (Puts a schedule onto an empty sheet and prints it):
ViewSheet sheet = ViewSheet.Create(Doc, ElementId.InvalidElementId);
Element view = new FilteredElementCollector(Doc)
.OfClass(typeof(ViewSchedule))
.Where(o => o.Name == element) //element is a string from a list of items in a WPF listbox.
.First();
ScheduleSheetInstance.Create(Doc, sheet.Id, view.Id, XYZ.Zero);
ViewSet set = new ViewSet();
set.Insert(sheet);
IList<ElementId> print = new List<ElementId>();
print.Add(sheet.Id);
Uidoc.Selection.SetElementIds(print);
printManager.PrintRange = PrintRange.Select;
ViewSheetSetting viewSheetSetting = printManager.ViewSheetSetting;
viewSheetSetting.CurrentViewSheetSet.Views = set;
printManager.SelectNewPrintDriver("Adobe PDF");
printManager.PrintToFile = true;
printManager.CombinedFile = true;
printManager.PrintToFileName = "TestFileName"; //ERROR HERE
printManager.Apply();
printManager.SubmitPrint(sheet);
Maybe you need to input the full path + name of the file to work.
Update: Found the problem in my formatting thanks to Bogdans post as well as This comment on the Autodesk Revit Api Forum.
Turns out, the PrintToFileName calls for both a path and a filename string. Working snippet is as follows:
string path = #"[same file path here ]";
string currentViewName = view.Name;
printManager.PrintToFileName = path + currentViewName + ".pdf";
printManager.Apply();
Thanks for the response, Bogdan.
I´m working on a project that uses Caliburn micro in wpf C#.
I´m in the process that I want to rewrite my method ReadMediaFile() so it displays all files in a folder in a list.
My method looks lite this:
private void ReadMediaFile()
{
string result;
_movieviewmodel = new MoviesViewModel();
string[] filePaths = Directory.GetFiles(#"C:/Users/v80770/Desktop/Movies/");
foreach (var file in filePaths)
{
result = Path.GetFileName(file);
_movieviewmodel.MovieName = result;
}
AddItem(_movieviewmodel);
}
When I debug the program all the files show in filePaths but only one shows in my list.
The AddItem is located in a class called TreeViewBase (belongs to caliburn micro I think) and it looks like this:
public void AddItem(T item)
{
_dispatcher.SmartInvoke(() => Items.Add(item));
}
I got the movie files viewing in my list but my MediaUri binding in view is bind against a specific path file but I want it to change dependent on what I choose
I tried to edit the binding to this:
string test = _movieviewmodel.MovieName;
MediaUri = new Uri(test);
But only get a exception "System.UriFormatException: 'Invalid URI: The format of the URI could not be determined.'"
Picture of Uri
New Uri code:
_movieviewmodel.MovieFilePath = #"C:/Users/v80770/Desktop/Movies/";
string test = _movieviewmodel.MovieFilePath;
MediaUri = new Uri(test + _movieviewmodel.MovieName);
But it always shows the same movie and my _movieviewmodel.MovieName does not change name dependent which movie I choose, it always is the same movie.
The creation of a MoviesViewModel item object and AddItem(_movieviewmodel); must be inside foreach, otherwise it would add only the last item:
foreach (var file in filePaths)
{
var movieviewmodel = new MoviesViewModel();
movieviewmodel.MovieName = Path.GetFileName(file);
AddItem(movieviewmodel);
}
or
foreach (var file in filePaths)
{
AddItem(new MoviesViewModel
{
MovieName = Path.GetFileName(file)
});
}
I have a combobox which gets the list of items from the name of files I put together in one directory, the purpose for this is to make it dynamic - I'm very new to c# and it didn't occur to me a different way. - Here's the code for that bit:
string[] files = Directory.GetFiles(templatePath);
foreach (string file in files)
cbTemplates.Items.Add(System.IO.Path.GetFileNameWithoutExtension(file));
Basically, that works just fine, it populates my combobox with the names of the files I have in that path, the problem is that I need to open the file that's selected in the combobox and read its contents and place them in labels, I was thinking maybe StreamReader would help me here but I have NO clue on how to implement it, I've searched the internet but it looks like no one had the same idea before me. Can someone please point me in the right direction? A link to something similar or a guide of the objects I need to use would be great, thanks!
what you should do is store the names of the files in a single separate file (csv or xml). then use this file to both load the combobox and as an indexer.
for example lets say you have files a.txt, b.txt, and c.txt. you should (as you already are) read the file names programmatically THEN write them to a new file in whichever format you want, including a unique index scheme (numbers work fine).
your csv might look like this:
1, a.txt,
2, b.txt,
3, c.txt,
from here you can parse the newly created csv to your liking. Use it to populate your combobox, index being its value and filename its text. Then you can read your combobox selectedvalue, get the proper filename from the csv index, and finally open the file.
It may be longwinded but it'll work. You could also just use a multidimensional array, but this is more fun from an educational stand point, and it will help you with read/write operations.
It is not so easy to understand your problem. Do you want just to display filename w/o extension in your combobox? I hope this code will be usefull to you.
internal class FileDetail
{
public string Display { get; set; }
public string FullName { get; set; }
}
public partial class Example: Form // This is just widows form. InitializeComponent is implemented in separate file.
{
public Example()
{
InitializeComponent();
filesList.SelectionChangeCommitted += filesListSelectionChanged;
filesList.Click += filesListClick;
filesList.DisplayMember = "Display";
}
private void filesListClick(object sender, EventArgs e)
{
var dir = new DirectoryInfo(_baseDirectory);
filesList.Items.AddRange(
(from fi in dir.GetFiles()
select new FileDetail
{
Display = Path.GetFileNameWithoutExtension(fi.Name),
FullName = fi.FullName
}).ToArray()
);
}
private void filesListSelectionChanged(object sender, EventArgs e)
{
var text = File.ReadAllText(
(filesList.SelectedItem as FileDetail).FullName
);
fileContent.Text = text;
}
private static readonly string _baseDirectory = #"C:/Windows/System32/";
}
Thanks for all your help folks but I figured out how to get around my issue, I'll post the code for future incidents. pd. Sorry it took me this long to reply, I was on vacation
string[] fname = Directory.GetFiles(templatePath); // Gets all the file names from the path assigned to templatePath and assigns it to the string array fname
// Begin sorting through the file names assigned to the string array fname
foreach (string file in fname)
{
// Remove the extension from the file names and compare the list with the dropdown selected item
if (System.IO.Path.GetFileNameWithoutExtension(file) != cbTemplates.SelectedItem.ToString())
{
// StreamReader gets the contents from the found file and assigns them to the labels
using (var obj = new StreamReader(File.OpenRead(file)))
{
lbl1.Content = obj.ReadLine();
lbl2.Content = obj.ReadLine();
lbl3.Content = obj.ReadLine();
lbl4.Content = obj.ReadLine();
lbl5.Content = obj.ReadLine();
lbl6.Content = obj.ReadLine();
lbl7.Content = obj.ReadLine();
lbl8.Content = obj.ReadLine();
lbl9.Content = obj.ReadLine();
lbl10.Content = obj.ReadLine();
obj.Dispose();
}
}
}