Invoking a combobox's selected folder(C#) - c#

I am using two comboboxes, in which 1st box will display folders in the specified location from that drop down list i will be selecting the necessary folder, so after selection the second combobox should list only the files depending on the 1st box's selected folder.(NOTE:Am not working with database, just accessing computers folder). Am working with visual studio 2013 in C#. Thanks in advance.
DirectoryInfo di = new DirectoryInfo(#"C:\Users\jeeva\Desktop\1234");
DirectoryInfo[] folders = di.GetDirectories();
comboBox1.DataSource = folders;
string selected =comboBox1.SelectedItem.ToString();
String fullpath = Path.Combine(#"C:\Users\jeeva\Desktop\1234", selected);
DirectoryInfo di1 = new DirectoryInfo(fullpath);
DirectoryInfo[] folders1 = di1.GetDirectories();
comboBox2.DataSource = folders1

It is done basically in 2 steps. You just need to separate them in your code.
1) get the folders into your combobox (may be already in the constructor of the Form):
DirectoryInfo di = new DirectoryInfo(#"C:\Users\jeeva\Desktop\1234");
DirectoryInfo[] folders = di.GetDirectories();
comboBox1.DataSource = folders;
2) double click comboBox1 in the designer. This will create an event which is triggered when the user selects an item. Inside it you can then get all the subfolders and give them as DataSource to the ComboBox which shall display them.
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string selected =comboBox1.SelectedItem.ToString();
String fullpath = Path.Combine(#"C:\Users\jeeva\Desktop\1234", selected);
DirectoryInfo di1 = new DirectoryInfo(fullpath);
DirectoryInfo[] folders1 = di1.GetDirectories();
comboBox2.DataSource = folders1
}

You can use Directory.GetFiles("folderName") method to populate your second combobox. Directory class resides in System.IO namespace.

You can get the folder list by something like this:
DirectoryInfo obj = new DirectoryInfo("E:\\");//you can set your directory path here
DirectoryInfo[] folders = obj.GetDirectories();
YourDirCombo.DataSource = folders ;
You probably have a method listening to your first combo changes:
private void YourDirCombo_SelectedIndexChanged(object sender, EventArgs e)
now in this you can get the files of the selected folder:
string [] fileEntries = Directory.GetFiles(YourDirCombo.SelectedValue);
YourFileCombo.DataSource = fileEntries;

The following can be optimized and generalized in several different ways - I'm doing it "long hand" to give you the most information possible.
private void initializeComboBoxes()
{
ComboBox c = new ComboBox();
c.Name = "cbx_One";
c.Items.Add("Select a File");
foreach(string direc in System.IO.Directory.GetDirectories(#"PathToYourFiles"))
{
c.Items.Add(direc);
}
c.SelectedIndex = 0;
c.SelectedIndexChanged += loadComboBox2;
Controls.Add(c);
ComboBox c1 = new ComboBox();
c1.Name = "cbx_Two";
c1.Items.Add("Waiting for file selection");
c1.SelectedIndex = 0;
c1.SelectedIndexChanged += loadFile;
Controls.Add(c1);
areComboBoxesUpdating = false;
}
bool areComboBoxesUpdating = true;
protected void loadComboBox2(object sender, EventArgs e)
{
if (!areComboBoxesUpdating)
{
ComboBox c1 = sender as ComboBox;
ComboBox c2 = Controls.Find("cbx_Two", true)[0] as ComboBox;
c2.Items.Clear();
if (c1.SelectedIndex == 0)
{
c2.Items.Add("Waiting for file selection");
}
else
{
c2.Items.Add("Please select a file");
//assuming c1 is the list of directories
foreach (string file in System.IO.Directory.GetFiles(c1.SelectedItem.ToString()))
{
c2.Items.Add(Path.GetFileName(c1.SelectedItem.ToString()));
}
}
areComboBoxesUpdating = true;
c2.SelectedIndex = 0;
areComboBoxesUpdating = false;
}
}
protected void loadFile(object sender, EventArgs e)
{
//a selection has been made from the second box - you have directory in box1 and filename in box2
ComboBox c = sender as ComboBox;
if (c.SelectedIndex > 0)
{
string directory = ((ComboBox)Controls.Find("cbx_One", true)[0]).SelectedItem.ToString();
string file = c.SelectedItem.ToString();
//do something
}
}

On the Onchange event of Combobox1:
ComboBox2.dataSource = System.IO.Directory.GetFiles(ComboBox1.SelectedText)
This should populate all the files in Combobox2

Related

How to manipulate or edit a txt file from textbox and save the modification to the main file or new file

I've managed to open a txt file to a ComboBox where it shown only the second element"100", and if I select one of the items in ComboBox will show me the the first element witch is "firstName", the problem is I want to modify the first element from the textbox and save it to the main file or new file on the way that I replace the old element with new one from the textbox and save the file as it was at the beginning
TXT FILE
firstName;;;100;;;0;
firstName;;;100;;;1;
firstName;;;100;;;2;
firstName;;;100;;;3;
firstName;;;0100;;;4;
firstName;;;0100;;;5;
firstName;;;0100;;;6;
firstName;;;0100;;;7;
lastName;;;0100;;;0;
lastName;;;0100;;;1;
lastName;;;0100;;;2;
lastName;;;0100;;;3;
lastName;;;0100;;;4;
lastName;;;0100;;;5;
lastName;;;0100;;;6;
lastName;;;0100;;;7;
i want to change the first elements from the textbox and replace it with user input and save the file as in it were,
example:
//output
john;;;100;;;0;
Patrick;;;100;;;1;
firstName;;;100;;;2;
namespace WindowsFormsApp8
{
public partial class Form1 : Form
{
public string[] lines;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.InitialDirectory = "c:\\";
openFileDialog.Filter = "txt file (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog.FilterIndex = 2;
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
//string[] lines = File.ReadAllLines(openFileDialog.FileName);
lines = File.ReadAllLines(openFileDialog.FileName);
List<string> result = new List<string>();
string[] par = new string[1];
par[0] = ";;;";
for (int i = 0; i < lines.Length; i++)
{
string[] row = lines[i].Split(par, StringSplitOptions.None);
if (row.Length > 2)
{
if (!result.Contains(row[1]))
result.Add(row[1]);
}
}
foreach (string line in result)
{
comboBox1.Items.Add(line);
}
}
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var d = lines;
var t = d.Where(g => g.Contains(comboBox1.Text));
string allItems = "";
foreach (string item in t)
{
string[] r = item.Split(new string[] { ";;;" }, StringSplitOptions.None);
allItems += r[0] + Environment.NewLine;
}
textBox1.Text = allItems;
}
}
}
I've read your code carefully and my understanding may not be perfect but it should be close enough that I can help. One way to achieve your objectives is with data binding and I'll demonstrate this step by step.
"open a txt file to a combobox"
In your main form, you'll move the OpenFileDialog so that it is now a member variable:
private OpenFileDialog openFileDialog = new OpenFileDialog
{
InitialDirectory = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"Files"),
FileName = "Data.txt",
Filter = "txt file (*.txt)|*.txt|All files (*.*)|*.*",
FilterIndex = 2,
RestoreDirectory = true,
};
In the main form CTor
Handle event buttonLoad.Click to display the dialog
Handle event openFileDialog.FileOk to read the file.
The DataSource of comboBox will be set to the list of lines read from the file.
Initialize
public MainForm()
{
InitializeComponent();
buttonLoad.Click += onClickLoad;
openFileDialog.FileOk += onFileOK;
comboBox.DataSource = lines;
.
.
.
Disposed += (sender, e) => openFileDialog.Dispose();
}
BindingList<Line> lines = new BindingList<Line>();
private void onClickLoad(object? sender, EventArgs e) =>
openFileDialog.ShowDialog();
In a minute, we'll look at those three things step by step. But first...
Serialize and Deserialize
You have a lot of loose code doing string splits to decode your serializer format. Try consolidating this in a class that is also suitable to be used in a BindingList<Line>. This will be the data source of your combo box. Also consider using a standard serialization format like JSON instead!
class Line : INotifyPropertyChanged
{
// Make a Line from serialized like firstName;;;100;;;0;
public Line(string serialized)
{
// Convert to a stored array
_deserialized = serialized.Split(new string[] { ";;;" }, StringSplitOptions.None);
}
// Convert back to the format used in your file.
public string Serialized => string.Join(";;;", _deserialized);
private string[] _deserialized { get; } // Backing store.
// Convert a list of Lines to a collection of strings (e.g. for Save).
public static IEnumerable<string> ToAllLines(IEnumerable<Line> lines) =>
lines.Select(_ => _.Serialized);
// Determine how a Line will be displayed in the combo box (e.g. "0100").
public override string ToString() => _deserialized[1].ToString();
// Use array syntax to access elements of the split array.
public string this[int index]
{
get => _deserialized[index];
set
{
if(!Equals(_deserialized[index],value))
{
// Send event when any array value changes.
_deserialized[index] = value;
OnPropertyChanged($"{index}");
}
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Load
Once the data file is selected, the raw text file will be shown and the combo box will be populated.
private void onFileOK(object? sender, CancelEventArgs e)
{
lines.Clear();
foreach (var serialized in File.ReadAllLines(openFileDialog.FileName))
{
lines.Add(new Line(serialized));
}
textBoxMultiline.Lines = lines.Select(_=>_.Serialized).ToArray();
comboBox.SelectedIndex = -1;
}
Replacement
Going back to the main form CTor there are three more events we care about:
public MainForm()
{
.
.
.
comboBox.SelectedIndexChanged += onComboBoxSelectedIndexChanged;
textBoxEditor.TextChanged += onEditorTextChanged;
lines.ListChanged += onListChanged;
.
.
.
}
When a new item is selected in the combo box, put it in the text editor.
private void onComboBoxSelectedIndexChanged(object sender, EventArgs e)
{
var item = (Line)comboBox.SelectedItem;
if (item != null)
{
textBoxEditor.Text = item[0];
}
}
When the textEditor text changes, modify the item.
private void onEditorTextChanged(object? sender, EventArgs e)
{
var item = (Line)comboBox.SelectedItem;
if (item != null)
{
item[0] = textBoxEditor.Text;
}
}
When the item changes, update the file display in the big textbox.
private void onListChanged(object? sender, ListChangedEventArgs e)
{
switch (e.ListChangedType)
{
case ListChangedType.ItemChanged:
textBoxMultiline.Lines = lines.Select(_=>_.Serialized).ToArray();
break;
}
}
Save
SaveFileDialog saveFileDialog = new SaveFileDialog
{
InitialDirectory = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"Files"),
FileName = "Data.txt",
Filter = "txt file (*.txt)|*.txt|All files (*.*)|*.*",
FilterIndex = 2,
RestoreDirectory = true,
};
private void onClickSave(object? sender, EventArgs e) =>
saveFileDialog.ShowDialog(this);
private void onSaveFileOK(object? sender, CancelEventArgs e)
{
File.WriteAllLines(saveFileDialog.FileName, Line.ToAllLines(lines));
}
I hope this is "close enough" to what you have described that if will give you some ideas to experiment with.

How to make difference between FileInfo and DirectoryInfo in a file explorer in list view

I would like to make a file explorer with Windows Forms, i already have done a few things, but when i would like to use the DoubleClick event of my ListView I dont know how to code that file explorer needs to act differently when I make the doubleclick on a file or a folder.
My goal is:
Clicking on a file - Loads its text into a TextBox
Clicking on a directory - Opens it and loads it into the listview.
I know how to do 1. and 2. as well, I just don't know how can I make my DoubleClick function know what the selected item in ListView was 1. or 2.
I build my ListView like this:
private void miOpen_Click(object sender, EventArgs e)
{
InputDialog dlg = new InputDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
DirectoryInfo parentDI = new DirectoryInfo(dlg.Path);
listView1.Items.Clear();
try
{
foreach (DirectoryInfo df in parentDI.GetDirectories())
{
ListViewItem lvi = new ListViewItem(new string[] {
df.Name, df.Parent.ToString(),
df.CreationTime.ToShortDateString(), df.FullName });
listView1.Items.Add(lvi);
}
foreach (FileInfo fi in parentDI.GetFiles())
{
ListViewItem lvi = new ListViewItem(new string[] {
fi.Name, fi.Length.ToString(),
fi.CreationTime.ToShortDateString(), fi.FullName } );
listView1.Items.Add(lvi);
}
}
catch { }
}
}
Add the DirectoryInfo or the FileInfo objects to the Tag property of the ListViewItem. I.e
...
var lvi = new ListViewItem(new string[] {
df.Name,
df.Parent.ToString(),
df.CreationTime.ToShortDateString(),
df.FullName
});
lvi.Tag = df;
listView1.Items.Add(lvi);
...
or for the file info:
lvi.Tag = fi;
Then, after having selected an item in the listview:
private void btnTest_Click(object sender, EventArgs e)
{
// Show the first item selected as an example.
if (listView1.SelectedItems.Count > 0) {
switch (listView1.SelectedItems[0].Tag) {
case DirectoryInfo di:
MessageBox.Show($"Directory = {di.Name}");
break;
case FileInfo fi:
MessageBox.Show($"File = {fi.Name}");
break;
default:
break;
}
}
}
Try this code:
FileAttributes fileAttributes = File.GetAttributes("C:\\file.txt");
if (fileAttributes.HasFlag(FileAttributes.Directory))
Console.WriteLine("This path is for directory");
else
Console.WriteLine("This path is for file");

Showing images into a list view

I am writing a code in C# to show the unknown number of images from a specified folder into a "listview" I don't know how to get all the files present in that specific folder.
I know I have to use a loop and array but I don't know how.
Here is the code which I use to access files with the "known name of file".
It's a windows form app.
private void btnZoom_Click(object sender, EventArgs e)
{
ImageList imgs = new ImageList();
imgs.ImageSize = new Size(100, 100);
string[] paths = { };
paths = Directory.GetFiles("TestFolder");
try
{
foreach (string path in paths)
{
imgs.Images.Add(Image.FromFile(path));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
listView1.SmallImageList = imgs;
listView1.Items.Add("2",0);
}
To get all the image files you can do
IEnumerable<string> paths = Directory.GetFiles(#"Your Dir", "*.*").Where(x=>x.EndsWith(".png") || x.EndsWith(".jpg")); //add all the extensions you wish in
then you can just iterate thru the list to add them in
Here is the working code:
and the code is :
private void button1_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
imageList1.Images.Clear();
string[] pics = System.IO.Directory.GetFiles( "pics//");
listView1.View = View.SmallIcon;
listView1.SmallImageList = imageList1;
imageList1.ImageSize = new Size(64, 64);
foreach (string pic in pics)
{
imageList1.Images.Add(Image.FromFile(pic));
}
for (int j = 0; j < imageList1.Images.Count; j++)
{
ListViewItem item = new ListViewItem();
item.ImageIndex = j;
listView1.Items.Add(item);
}
}
and at designer set this:

Open image from listbox file name C# winform

I have been working on this in my spare time, to no avail. I really could use a hand getting this to work.
I have a winform in C#. I am currently working with a listbox and a picturebox to display embedded image resources. I want to populate the listbox with just the file name, as the full path is longer than the width of the listbox can accommodate on my form.
Here is some code I was working with:
string[] x = System.IO.Directory.GetFiles(#"C:\Users\bassp\Dropbox\VS Projects\WindowsFormsApplication1\WindowsFormsApplication1\Resources\", "*.jpg");
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
foreach (string f in x)
{
string entry1 = Path.GetFullPath(f);
string entry = Path.GetFileNameWithoutExtension(f);
listBox1.DisplayMember = entry;
listBox1.ValueMember = entry1;
listBox1.Items.Add(entry);
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
pictureBox1.ImageLocation = listBox1.SelectedItem.ToString();
}
If I populate the listbox with the full path,(entry1), things work pretty smooth other than not being able to see the image name you will be selecting due to the length of the full path.
When I try to populate the listbox with (entry), just the file names appear in the listbox, which is desireable, however, the image will no longer open on selection from the listbox.
How can I get this working correctly? Help is greatly appreciated.
Patrick
You're on the right track by setting the DisplayMember and ValueMember properties, but you'd need to make a few corrections, and it might not be necessary here.
Store the original directory path in a separate variable, then just combine that with the file name in your SelectedIndexChanged event to get the original file path.
string basePath =
#"C:\Users\bassp\Dropbox\VS Projects\WindowsFormsApplication1\WindowsFormsApplication1\Resources\";
string[] x = Directory.GetFiles(basePath, "*.jpg");
foreach (string f in x)
{
listBox1.Items.Add(Path.GetFileNameWithoutExtension(f));
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
pictureBox1.ImageLocation =
Path.Combine(basePath, listBox1.SelectedItem.ToString()) + ".jpg";
}
Grant answer is perfectly ok for a simple task like this, but i'll explain another way that may be useful in other situations.
You can define a class to store your filenames and paths, something like:
class images
{
public string filename { get; set; }
public string fullpath { get; set; }
}
This way, your code could be like:
string[] x = System.IO.Directory.GetFiles(#"C:\Users\bassp\Dropbox\VS Projects\WindowsFormsApplication1\WindowsFormsApplication1\Resources\", "*.jpg");
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
List<images> imagelist=new List<images>();
foreach (string f in x)
{
images img= new images();
img.fullpath = Path.GetFullPath(f);
img.filename = Path.GetFileNameWithoutExtension(f);
imagelist.Add(img);
}
listBox1.DisplayMember = "filename";
listBox1.ValueMember = "fullpath";
listBox1.DataSource = imagelist;
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
pictureBox1.ImageLocation = ((images)listBox1.SelectedItem).fullpath;
}
I have not tested it,maybe it has any typo, but i hope you get the idea.

Window Media PLayer in C#

i'm building a Music PLayer and so i choose to use the library of Window Media Player:
Now i got stuck 'cos i wish show the song's name in a listBox and change songs in real time but i don't know how go on.
I store songs from a Folder and so when the Music Player run the songs from the Url choose.
I show you a code snippet :
private void PlaylistMidday(String folder, string extendsion)
{
string myPlaylist = "D:\\Music\\The_Chemical_Brothers-Do_It_Again-(US_CDM)-2007-SAW\\";
ListView musicList = new ListView();
WMPLib.IWMPPlaylist pl;
WMPLib.IWMPPlaylistArray plItems;
plItems = player1.playlistCollection.getByName(myPlaylist);
if (plItems.count == 0)
pl = player1.playlistCollection.newPlaylist(myPlaylist);
else
pl = plItems.Item(0);
DirectoryInfo dir = new DirectoryInfo(folder);
FileInfo[] files = dir.GetFiles(extendsion, SearchOption.AllDirectories);
foreach (FileInfo file in files)
{
string musicFile01 = file.FullName;
string mName = file.Name;
ListViewItem item = new ListViewItem(mName);
musicList.Items.Add(item);
WMPLib.IWMPMedia m1 = player1.newMedia(musicFile01);
pl.appendItem(m1);
}
player1.currentPlaylist = pl;
player1.Ctlcontrols.play();
}
On Load i decide to play the songs of "myPLaylist" so i ask you do you know some way how to show the songs of my playlist in a listbox and when i click on the selected item i will change songs?
Thansk for your support.
Nice Regards
Instead of adding songs to playlist, you can add them to a List<string> as a return value. On load event, you just call the method that get list of media file paths in the folder, and then add them into a listbox.
To change the song being played, you just need to add SelectedValueChanged/SelectedItemChanged event, and in this event, get the file path that is currently selected in the listbox, then have WMP played it for you :)
private void Form1_Load(object sender, EventArgs e)
{
List<string> str = GetListOfFiles(#"D:\Music\Bee Gees - Their Greatest Hits - The Record");
listBox1.DataSource = str;
listBox1.DisplayMember = "str";
}
private List<string> GetListOfFiles(string Folder)
{
DirectoryInfo dir = new DirectoryInfo(Folder);
FileInfo[] files = dir.GetFiles("*.mp3", SearchOption.AllDirectories);
List<string> str = new List<string>();
foreach (FileInfo file in files)
{
str.Add(file.FullName);
}
return str;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string strSelected = listBox1.SelectedValue.ToString();
MessageBox.Show(strSelected); //Just demo, you can add code that have WMP played this file here
}
a quick solution. :). Not very good, but it works. Help this hope

Categories

Resources