C# Pass file path from file in listbox to dataconext - c#

I am populating a listbox with a file. This can be done by two methods, the open file dialog command initiated by a button press and a drag/drop action into the listbox. I want to pass on the file path (for the file in the listbox) to other areas of my code. Such as a DataContext that reads the file in the listbox. Basically I want the file path to automatically update when the listbox is populated. I am new to C# so sorry if I haven't explained myself properly or provided enough information. The code for populating my listbox (named FilePathBox) and the 'Run' button is as follows:
private void BrowseButton_Click(object sender, RoutedEventArgs e)
{
var openFileDialog = new Microsoft.Win32.OpenFileDialog();
//openFileDialog.Multiselect = true;
openFileDialog.Filter = "Csv files(*.Csv)|*.Csv|All files(*.*)|*.*";
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
if (openFileDialog.ShowDialog())
{
FilePathBox.Items.Clear();
foreach (string filename in openFileDialog.FileNames)
{
ListBoxItem selectedFile = new ListBoxItem();
selectedFile.Content = System.IO.Path.GetFileNameWithoutExtension(filename);
selectedFile.ToolTip = filename;
FilePathBox.Items.Add(selectedFile);
}
}
}
private void FilesDropped(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
FilePathBox.Items.Clear();
string[] droppedFilePaths = e.Data.GetData(DataFormats.FileDrop, true) as string[];
foreach (string droppedFilePath in droppedFilePaths)
{
ListBoxItem fileItem = new ListBoxItem();
fileItem.Content = System.IO.Path.GetFileNameWithoutExtension(droppedFilePath);
fileItem.ToolTip = droppedFilePath;
FilePathBox.Items.Add(fileItem);
}
}
}
private void RunButton_Click(object sender, RoutedEventArgs e)
{
DataContext = OldNewService.ReadFile(#"C:\Users\Documents\Lookup Table.csv");
}

Refer the below code.
<StackPanel>
<ListBox x:Name="fileList" Height="100" Drop="fileList_Drop" DisplayMemberPath="Name" AllowDrop="True"/>
<Button Content="Browse" Click="Button_Click"/>
<Rectangle/>
</StackPanel>
public partial class MainWindow : Window
{
ObservableCollection<FileInfo> lst = new ObservableCollection<FileInfo>();
public MainWindow()
{
InitializeComponent();
fileList.ItemsSource = lst;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
if ((bool)dlg.ShowDialog())
{
FileInfo fi= new FileInfo(dlg.FileName);
lst.Add(fi);
}
}
private void fileList_Drop(object sender, DragEventArgs e)
{
string[] droppedFilePaths = e.Data.GetData(DataFormats.FileDrop, true) as string[];
foreach (string droppedFilePath in droppedFilePaths)
{
FileInfo fi = new FileInfo(droppedFilePath);
lst.Add(fi);
}
}
}

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.

Promblemas to send to call my method to a button

I am learning to program in C # so my question is how to call the method from the button3
Look for information on the web but it is not very clear to me why I turn to this site
private void button3_Click_1(object sender, EventArgs e)
{
}
private void export2File(ListView lv, string splitter)
{
string filename = "";
SaveFileDialog sfd = new SaveFileDialog();
sfd.Title = "SaveFileDialog Export2File";
sfd.Filter = "Text File (.txt) | *.txt";
if (sfd.ShowDialog() == DialogResult.OK)
{
filename = sfd.FileName.ToString();
if (filename != "")
{
using (StreamWriter sw = new StreamWriter(filename))
{
foreach (ListViewItem item in lv.Items)
{
sw.WriteLine("{0}{1}{2}", item.SubItems[0].Text, splitter, item.SubItems[1].Text);
}
}
}
}
}
private void button3_Click_1(object sender, EventArgs e)
{
ListView listView1 = new ListView();
string splitter = ",";
export2File(listview1, splitter);
}
You need to pass a reference to the ListView on your Form, and the desired "splitter" into the method. Assuming listView1 and a comma:
private void button3_Click_1(object sender, EventArgs e)
{
export2File(listView1, ",");
}

Load JSON File to ListBox and TextBox C#

I'm working on a Windows Form Application. Textbox index can be saved and shown as in ListBox with this code:
private List<FunctionData> funcParamList = new List<FunctionData>();
...
private void addFuncButton_Click(object sender, EventArgs e)
{
FunctionData funcParams = new FunctionData();
funcParams.blabla1name = blabla1.Text;
funcParams.blabla2name = blabla2.Text;
...
if (funcParams.isValid())
{
funcParamList.Add(funcParams);
functionListBox.Items.Add(functionNameBox.Text);
}
Also I collect objects to TextBox again to edit (by clicking ListBox item) with the following code :
private void getParams(FunctionData data)
{
blabla1.Text = data.blabla1name;
blabla2.Text = data.blabla2name;
functionNameBox.Text = data.functionName;
return;
}
private void functionListBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (functionListBox.SelectedItem == null) { return; }
foreach (var obj in funcParamList)
{
if (obj.functionName == functionListBox.SelectedItem.ToString())
{
getParams(obj);
}
}
}
And save them to file as JSON with:
private void saveFileButton_Click(object sender, EventArgs e)
{
fileName = fileNameBox.Text;
string jsonFunc = JsonConvert.SerializeObject(funcParamList);
System.IO.File.WriteAllText(#"<blablapath>\" + fileName + ".txt", jsonFunc);
}
There's 'functionName' object in JSON file that I can use it for showing on ListBox.
My question is: How can I load this file buy Native Load/Open File Dialog and show the objects in ListBox and can edit them again?
And here how I've tried to make it with the following code, but it doesn't work:
private void loadFileButton_Click(object sender, EventArgs e)
{
OpenFileDialog loadFileDialog = new OpenFileDialog();
...
if (loadFileDialog.ShowDialog() == DialogResult.OK)
{
string jsonFileName = loadFileDialog.FileName;
string jsonFile = File.ReadAllText(jsonFileName);
dynamic loadedFile = JsonConvert.DeserializeObject(jsonFile);
//if (functionListBox.SelectedItem == null) { return; }
foreach (var obj in loadedFile)
{
if (obj.functionName != null)
{
functionListBox.Items.Add(obj.functionName);
getParams(obj); // I get exception here
funcParamList.Add(loadedFile);
functionListBox.Refresh();
}
}
}
I've solved the problem by casting 'DeserializeObject' as List and it's done. Here the changes:
...
var loadedFile = JsonConvert.DeserializeObject<List<FunctionData>>(jsonFile);

compress Data from listbox using ZipFile

I am creating button click event, on clicking it will select data of textbox1 and comboBox1. Further it will search for specific file type from the folder name I provide into textbox1. Currently I am using listbox1 as container for storing value from combobox and textbox. Now I want to Zip the file I got from listbox1. I am using ZipFile to compress it.Now I am stuck in how to call all data from listbox1 for compressing.
namespace WinDataStore
{
public partial class Form1 : Form
{
ComboBox comboBox;
public Form1()
{
InitializeComponent();
var daysOfWeek =
new[] { "RED", "GREEN", "BLUE"
};
comboBox = new ComboBox
{
DataSource = daysOfWeek,
Location = new System.Drawing.Point(180, 140),
Name = "comboBox",
Size = new System.Drawing.Size(166, 21),
DropDownStyle = ComboBoxStyle.DropDownList
};
this.Controls.Add(comboBox);
}
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog folderBrowserDlg = new FolderBrowserDialog();
folderBrowserDlg.ShowNewFolderButton = true;
DialogResult dlgResult = folderBrowserDlg.ShowDialog();
if (dlgResult.Equals(DialogResult.OK))
{
textBox1.Text = folderBrowserDlg.SelectedPath;
Environment.SpecialFolder rootFolder = folderBrowserDlg.RootFolder;
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBox1.Text))
{
//notification to user
return;
}
string[] extensions = { ".xml",".ddg" };
string[] dizin = Directory.GetFiles(textBox1.Text, "*.*",SearchOption.AllDirectories)
.Where(f => extensions.Contains(new FileInfo(f).Extension.ToLower())).ToArray();
listBox1.Items.AddRange(dizin);
var comboBox = this.Controls["comboBox"] as ComboBox;
string s = (string)comboBox.SelectedItem;
listBox1.Items.Add(s);
}
}
}

C# - Create dynamic buttons and events

I have a form with a tabControl and inside of each tab is a flowLayoutPanel where I can drag and drop files and a button is created for each dropped file. Afterwards when I click on a button, the file that i dropped should open. I have managed to do this for one file only.. My problem is how can I tell which button was clicked and to open the file/app stored in the path for each button.. How can I differentiate in the button_click event the clicked button and the path of the app to open?
Code for this part so far:
Process myProcess = new Process();
string path_app;
public Form1()
{
InitializeComponent();
this.DragEnter += new DragEventHandler(Form1_DragEnter);
this.DragDrop += new DragEventHandler(Form1_DragDrop);
}
void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
e.Effect = DragDropEffects.All;
}
void Form1_DragDrop(object sender, DragEventArgs e)
{
string[] fileList = e.Data.GetData(DataFormats.FileDrop) as string[];
foreach (string s in fileList)
{
Button button = new Button();
button.Click += new EventHandler(this.button_Click);
flowLayoutPanel1.Controls.Add(button);
path_app = String.Format("{0}", s);
}
}
private void button_Click(object sender, System.EventArgs e)
{
myProcess.StartInfo.FileName =path_app;
myProcess.Start();
}
Also my tabControl has the possibility to add new tabs but how can I get the selected tab and the inside flowLayoutPanel to know where to create the button?
And by the way, is there a problem of how I open the files? I understood that i have to take into consideration the working directory..
Thank you for your help!
You can utilize Tag property of the Button:
void Form1_DragDrop(object sender, DragEventArgs e)
{
foreach (String s e.Data.GetData(DataFormats.FileDrop))
{
Button button = new Button();
button.Click += new EventHandler(this.button_Click);
flowLayoutPanel1.Controls.Add(button);
path_app = String.Format("{0}", s);
// Add to Tag any data you want to pin to the button
button.Tag = path_app;
}
}
private void button_Click(object sender, System.EventArgs e)
{
// Obtain via Tag
String path_app = ((sender as Button).Tag as String);
myProcess.StartInfo.FileName = path_app;
myProcess.Start();
}
You could use button.Tag = "theFancyPath" and in the EventHandler cast the object sender as Button to access the Tag property.
If you need more then you could inherit from Button:
public class ButtonWithPathProperty : Button
{
public FileInfo PathToOpen { get; private set; }
public ButtonWithPathProperty(FileInfo path)
{
PathToOpen = path;
this.Click += new EventHandler(this.button_Click);
}
private void button_Click(object sender, System.EventArgs e)
{
var yourPath = this.PathToOpen;
}
}
This is not tested btw :)

Categories

Resources