Downloading Multiple Files From the Items in Listbox - c#

I tried figuring out the following issue but I am not able to do it as I just started programming a month ago.
I have a listbox of 20 items:
private void loadDownloadXMLListBox()
{
var items = new[] { "BARC", "DEV", "DOM", "EZJ", "GFS",
"IHG", "JD.", "LAD", "LLOY", "MRW",
"NXT", "OCDO", "RBS", "SMWH", "SPD",
"STAN", "SYR", "TALK", "TSCO", "WMH" };
foreach (var item in items) listDownloadXML.Items.Add(item);
listDownloadXML.SelectedIndex = -1;
}
This is my code for downloading a single selected file from a website:
private void btnDownloadXML_Click(object sender, EventArgs e)
{
using (WebClient client = new WebClient())
{
client.DownloadFile("http://www.lse.co.uk/chat/" + listDownloadXML.SelectedItem,
#"..\..\sharePriceXML\" +
listDownloadXML.SelectedItem + ".xml");
}
MessageBox.Show("Download Completed! File has been placed in the folder sharePriceXML!");
}
I want to click on a button "Download All" then, all the 20 items from the website will be downloaded. May I know how can I loop through the 20 items in the listbox and download them all into a folder without selecting item(s)? Thank you.

foreach (var item in listDownloadXML.Items)
{
//... your code to download "item".
}

You could start by externalizing the download a single file functionality into a separate, reusable method:
public void DownloadFile(string item)
{
using (var client = new WebClient())
{
client.DownloadFile(
"http://www.lse.co.uk/chat/" + item,
#"..\..\sharePriceXML\" + item + ".xml"
);
}
MessageBox.Show("Download Completed! File has been placed in the folder sharePriceXML!");
}
and then:
private void btnDownloadXML_Click(object sender, EventArgs e)
{
DownloadFile((string)listDownloadXML.SelectedItem);
}
and now to your question about multiple files => you use a loop and call the DownloadFile method for each element in the listbox:
foreach (string item in listDownloadXML.Items)
{
DownloadFile(item);
}

Related

How to copy multiple items to clipboard history in c#?

I'm using the clipboard class from Win API (Windows.ApplicationModel.DataTransfer.Clipboard). When I try to copy multiple items one by one to the clipboard history, it gets overwritten by the recent item. I want to store every item I copy onto the clipboard history. My clipboard history is enabled and I tried using all of the set methods from clipboard including the SetText method from (System.Windows.Clipboard) and all of which overwrites instead of adding to history.
private void UpdateClipboardOnProfileDropDownClosed(object sender, EventArgs e)
{
Clipboard.ClearHistory();
using (var db = new LiteDatabase(Path.Combine(documents, "Auto Paste Clipboard", "data.db")))
{
var collection = db.GetCollection<ClipboardProfile>("clipboard");
var clipboard = collection.FindOne(x => x.Profile == ProfileComboBox.Text);
clipboard.Clipboard.Reverse();
MessageBox.Show(clipboard.Clipboard.Count.ToString());
foreach (var item in clipboard.Clipboard)
{
DataPackage data = new DataPackage
{
RequestedOperation = DataPackageOperation.Copy
};
data.SetText(item);
Clipboard.SetContent(data);
}
}
}
It takes some delays for Clipboard history to save the current item. Therefore, you could try to add a delay when an item is added.
Please check the following code as a sample:
private async void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
if(Clipboard.IsHistoryEnabled())
{
List<string> lists=new List<string>{ "1","2","3","4","5","6","7","8","9","10"};
foreach(var item in lists)
{
DataPackage dataPackage = new DataPackage();
dataPackage.SetText(item);
Clipboard.SetContent(dataPackage);
await Task.Delay(250);
}
}
}
Note, if these items are not all added, you could increase the delay time.

Delete files displayed in a listbox in c#?

I have a listbox which displays the results of a file search in Windows.
What I'd like to be able to do is press the delete key whilst the item/s is highlighted and have the actual file deleted from the system.
I have it working for directories with Directory.Delete(obj.ToString()); but I can't get the following to work for files, if someone could help it would be appreciated. I get an illegal characters error after I press the Del key.
private void listBoxResults_KeyDown(object sender, KeyEventArgs e)
{
if (btnFilesClicked == true)
{
if (e.KeyCode == Keys.Delete)
{
List<int> sItems = new List<int>();
foreach (var obj in listBoxResults.SelectedIndices)
{
sItems.Add(Convert.ToInt32(obj));
}
foreach (var obj in listBoxResults.SelectedItems)
{
try
{
File.Delete(obj.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
foreach (int item in sItems.OrderByDescending(x => x))
{
listBoxResults.Items.RemoveAt(item);
}
}
}
First of all ListBox.SelectedItems Is an instance of IList which is not a generic implementation so it would give you only object instance...!
Have a look at this msdn link for ListBox.SelectedItems
Second thing When you will invoke ToString() on obj it's default implementation would return you type name.
This is the reason your code is not working exactly how you wanted.
try
{
File.Delete(obj.ToString()); // this requires file name not the type name
}
You need to some how get the fileName first and then you can call Delete method like below.
try
{
var fileName = GetFileName();
File.Delete(fileName);
}

Simple yet frustrating Listbox and Texbox search again

I have spent few days searching everywhere for a solution to this.
This is for C# with Visual Studio 2013 (ya, I am a newbie):
two textboxes (Last name and First Name) and a listbox with 5 names (Higgins M, Higgins J, King J, Tran A, Dempsey S). I set listbox property as sorted.
if I select Higgins J in listbox, then the word Higgins should appear in Last Name textbox and J should appear in First Name textbox.
if I type Higgins in Last Name textbox, Higgins J should be the selected item in listbox (Higgins J will be selected before Higgins M). If I type M in the First Name textbox, the selected item should change from Higgins J to Higgins M.
but....here are the problems that made me decide to create an account here:
If I type Hi or Hig instead of Higgins, it has to stay that way, it does not become Higgins in the textbox. Only the index/highlight in listbox is changed, not the entry in textbox (whatever I type in the textbox stays). I suspect the events that I use are the reason I cannot get this done. Textbox_textchanged and listbox_selectedindexchanged. So whatever I do in one event will automatically triggers the other. I have tried changing the events, but so far the result simply worse. Using: if (LastName_textbox.Text = "") did not help either.
How do I combine Last Name and First Name as one index?
I apologise if this question has appeared or sounded ambiguous. I suppose I do not know how to phrase the search to get something similar to my problem and English is not my first language. Any help is very much appreciated .Thanks.
Here is part of the codes:
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Project
{
public partial class frmContact : Form
{
//declare file to save all contacts
private string fileName = Directory.GetCurrentDirectory() + "\\Contacts.txt";
//create temporary file for updating and deleting contacts
private string newContacts = Directory.GetCurrentDirectory() + "\\newContacts.txt";
public frmContact()
{
InitializeComponent();
}
private void frmContact_Load(object sender, EventArgs e)
{
//create Contacts.txt if it does not exist
if (!File.Exists(fileName))
{
File.Create(fileName).Close();
MessageBox.Show("New " + fileName +" Has Been Created");
tbLast.Select();
}
//if file already exists
else
{
StreamReader readOb = new StreamReader(fileName);
using (readOb)
{
while (!readOb.EndOfStream)
{
string rdLine = readOb.ReadLine(); //read data in file by line
string[] tmpArr = rdLine.Split(',');
lbContact.Items.Add(tmpArr[0] + "," + tmpArr[1]);
}
tbLast.Select();
}
}
}
private void lbContact_SelectedIndexChanged(object sender, EventArgs e)
{
//show details of contact selected in listbox
string findNames = lbContact.GetItemText(lbContact.SelectedItem);
StreamReader obRead = new StreamReader(fileName);
using (obRead)
{
while (!obRead.EndOfStream)
{
string rdLine = obRead.ReadLine();
if (rdLine.StartsWith(findNames))
{
string[] tmpArr = rdLine.Split(',');
tbLast.Text = tmpArr[0];
tbFirst.Text = tmpArr[1].Trim();
tbAddr.Text = tmpArr[2].Trim();
tbSub.Text = tmpArr[3].Trim();
tbPost.Text = tmpArr[4].Trim();
tbEmail.Text = tmpArr[5].Trim();
tbPhone.Text = tmpArr[6].Trim();
tbMob.Text = tmpArr[7].Trim();
}
}
lbContact.SelectedIndex = lbContact.FindString(findNames);
}
}
private void tbLast_TextChanged(object sender, EventArgs e)
{
lbContact.SelectedItem = lbContact.FindString(tbLast.Text);
}
A simple (but kind of ugly solution) would consist in using a boolean value to inform your lbContact_SelectedIndexChanged method that the index was manually changed thanks to the code. A class member would do the job, something like:
private bool fromCode;
private void lbContact_SelectedIndexChanged(object sender, EventArgs e)
{
if (fromCode)
return;
// Do the job
}
private void tbLast_TextChanged(object sender, EventArgs e)
{
fromCode = true;
lbContact.SetSelected(lbContact.FindString(tbLast.Text), true);
fromCode = false;
}
[Personal remark]
I would also create a Contact struct/class to store your information along with a collection in your form so that you only have to access your file twice:
At loading, so that you can populate your collection
At closing, so that you can save the changes to your file
[Update]
My last remark can be not relevant as I do not have the context in which you are developing your application, that's why I said it was a personal point of view, you don't have to do it.
[Update 2]
What you can do to avoid access your file each time your lbContact_SelectedIndexChanged event is called:
Create a structure or a class to store your contacts information (firstname, lastname, adress, ...)
Create a collection (as a class member of your form) that will contain the contacts (like a List<Contact>)
In your frmContact_Load method, fill this collection with the data contained in the file instead of populating your listbox
So that in your lbContact_SelectedIndexChanged method you will search inside the collection instead of opening your file
Your Add() and Delete() operations must also modify the collection and not the file anymore
Remember to save your collection back to your file at application closing
Hope it helped.
I found the solution (for whoever encounters similar problem), the answer is in the textbox.focused :) and combined with listbox.setselected from Tim.
private void tbLast_TextChanged(object sender, EventArgs e)
{
if (tbLast.Focused && tbLast.Text != "")
{
if (lbContact.FindString(tbLast.Text) > -1)
{
lbContact.SetSelected(lbContact.FindString(tbLast.Text), true);
}
}
}
private void lbContact_SelectedIndexChanged(object sender, EventArgs e)
{
//show details of contact selected in listbox
string findNames = lbContact.GetItemText(lbContact.SelectedItem);
StreamReader obRead = new StreamReader(fileName);
using (obRead)
{
while (!obRead.EndOfStream)
{
string rdLine = obRead.ReadLine();
if (rdLine.StartsWith(findNames))
{
string[] tmpArr = rdLine.Split(',');
if (!tbLast.Focused)
{
tbLast.Text = tmpArr[0];
tbFirst.Text = tmpArr[1].Trim();
tbAddr.Text = tmpArr[2].Trim();
tbSub.Text = tmpArr[3].Trim();
tbPost.Text = tmpArr[4].Trim();
tbEmail.Text = tmpArr[5].Trim();
tbPhone.Text = tmpArr[6].Trim();
tbMob.Text = tmpArr[7].Trim();
}
}
}
lbContact.SelectedIndex = lbContact.FindString(findNames);
}
}

How to fill a textbox with an external textfile and add words into it after this

I am trying to fill a visual studio 2012 textbox with the data from an external text file and after this, when you execute the programme, you should be able to write changes to this TextBox and save them there, but i get the error, illustrated in the screenshot. Moreover, I am running Windows 8 on a virtual machine !
[screenshot]: http://i.imgur.com/NkZU38C.png "Screenshot
Here is the codefor filling the textbox:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
LoadWords(#"Assets\AdminPageKS1words.txt");
}
async private void LoadWords(string filename)
{
var wordList = new List<String>();
// this method reads line separated words from a text file and populates a List object //
Windows.Storage.StorageFolder localFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
// begin the file read operation
try
{
// open and read in the word list into an object called words
StorageFile sampleFile = await localFolder.GetFileAsync(filename);
var words = await FileIO.ReadLinesAsync(sampleFile);
// add each word returned to a list of words declared
// globally as List wordList = new List();
foreach (var word in words)
{
wordList.Add(word);
}
List1.ItemsSource = wordList;
}
catch (Exception)
{
// handle any errors with reading the file
}
And here is the code for the SAVE button:
async private void SaveButton_Click(object sender, RoutedEventArgs e)
{
// locate the local storage folder on the device
Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
// create a new text file in the local folder called “File.txt”
StorageFile sampleFile = await localFolder.CreateFileAsync("File.txt",CreationCollisionOption.ReplaceExisting);
// write text to the file just created – text comes from a textblock called wordlistBox
await FileIO.WriteTextAsync(sampleFile, List1.Text);
// display a message saying that file is saved.
messageLabel.Text = keystage + "File saved";
}
public string keystage { get; set; }
As the error message says, List1 (a TextBox) doesn't have an ItemsSource property. It has a Text property.
But that's not the only problem. Because your wordList object is an IList. So you'll need to turn that into a plain string.
One solution would be to do this:
List1.Text = string.Join(Environment.NewLine, wordlist);
which would concatenate all of the lines together with line breaks in between.
Also make sure that your TextBox is configured properly with AcceptsReturn set to true so that it will display the line breaks.
As I see List1 is a TextBox , rather than a ListBox, try:
.......
string text="";
foreach (var word in words)
{
text+=word+" ";
}
List1.Text=text;
Alternatively you can define a ListBox listbox1:
foreach (var word in words)
{
wordList.Add(word);
}
listbox1.ItemsSource = wordList;

How to write into same xml file from two pages?

I have Single.cs and Periodic.cs files, which have Button_Click events, and user should add some information into same file by pressing these buttons. Implementation of Button_Click is almost same, this is why I show only one them.
using System.IO;
//.........
namespace ModernUIApp1.Pages
{
public partial class Home : UserControl
{
private void Button_Click(object sender, RoutedEventArgs e)
{
// this is how i get required path
var systemPath = System.Environment.GetFolderPath(
Environment.SpecialFolder.CommonApplicationData);
var _directoryName1 = Path.Combine(systemPath, "RadiolocationQ");
string script = "script";
string path_scriprt1 = Path.Combine(_directoryName1, script+".xml");
cur_script.Add(new XElement("Single_Request" + Convert.ToString(num),
new XElement("numRequest", TxtBlock_numRequest.Text),
));
cur_script.Save(path_scriprt1);
num++; // I use this to create unique name
}
XElement cur_script = new XElement("Requestes");
int num = 1;
}
}
Eventually, user can push buttons many times, and this code will work fine if I dont use these buttons at the same time. Because otherwise it simply overwrites existing information. So the problem is to make this XElement cur_script = new XElement("Requestes"); global. Or do you have some other ways out?
The real issue is that you need to avoid concurrency issue here. What if you have two persons try to update the same file and the following sequences occurs:
User 1 open and load the file;
User 2 open and load the file;
User 1 modify the xml and save it;
User 2 modify the xml and save it;
In this case the change made by user 1 will be lost.
To avoid this problem you want to keep the file open until your have saved it. For example:
using (FileStream stream =
File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
....load xml, modify it, and save it
}
public void WriteToDoc(XmlDocument doc, XElement element)
{
// this method can reside somewhere outside.
// some generic doc loader can load the doc
// add element to doc
}
public void OnButton1Click(object sender, RoutedEventArgs e)
{
// do something with element
WriteToDoc( mydoc, myNewElement)
}
public void OnButton2Click(object sender, RoutedEventArgs e)
{
// do something else with element
WriteToDoc( mydoc, myNewElement)
}
V2
public class ElementAdder
{
public static void WriteToDoc(string path, XElement element)
{
// load doc based on path
// add element to doc
}
}
public void OnButton1Click(object sender, RoutedEventArgs e)
{
// do something with element
string path = ConfigMan.GetDocPath();
ElementAdder.WriteToDoc(path, myNewElement);
}
public void OnButton2Click(object sender, RoutedEventArgs e)
{
// do something else with element
string path = ConfigMan.GetDocPath();
ElementAdder.WriteToDoc(path, myNewElement);
}
Thank you for help, but I solved problem on my own. I just used tips how to write into same xml-file, this way:
XDocument Requestes = XDocument.Load(path_scriprt1);
XElement newElement = new XElement("Single_Request" + Convert.ToString(num),
new XElement("numRequest", TxtBlock_numRequest.Text),
new XElement("IDWork", TxtBlock_IDWork.Text),
new XElement("NumObject", TxtBlock_NumObject.Text),
new XElement("lvlPriority", CmbBox_lvlPriority.Text),
new XElement("NumIn1Period", TxtBlock_NumIn1Period.Text)
);
Requestes.Descendants("Requestes").First().Add(newElement);
Requestes.Save(path_scriprt1);

Categories

Resources