The user can click an item in a ListBox as follows:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
textBox2.Clear();
listBox2.Items.Clear();
string[] p =
Directory.GetFiles(
textBoxDir.Text,
listBox1.SelectedItem.ToString(),
SearchOption.AllDirectories);
foreach (string open in p)
......
}
All is fine. However if the user clicks on an empty space in the ListBox, it displays the following error:
System.NullReferenceException
This is because of this line of code:
string[] p =
Directory.GetFiles(
textBoxDir.Text,
listBox1.SelectedItem.ToString(),
SearchOption.AllDirectories);
Does anyone have a clever work around? Or suggest an aalternative to my code?
The workaround is to check for a null value, and exit early.
if (listBox1.SelectedItem == null)
{
return;
}
This avoids the nesting introduced by the other answers, which makes the code less readable.
You can check SelectedIndex before that line:
if(listBox2.SelectedIndex < 0)
return;
How about doing a
if(listBox1.SelectedItem != null){
// ... do your work with listBox1.SelectedItem here
}
that should prevent that error from happening.
How about
if (listBox1.SelectedItem != null)
{
string[] p = Directory.GetFiles(textBoxDir.Text, listBox1.SelectedItem.ToString(), SearchOption.AllDirectories);
}
Full Code
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox1.SelectedItem != null)
{
textBox2.Clear();
listBox2.Items.Clear();
string[] p = Directory.GetFiles(textBoxDir.Text, listBox1.SelectedItem.ToString(), SearchOption.AllDirectories);
foreach (string open in p)
...... }
}
}
just check first if listbox1.SelectedItem is empty or not prior to calling this line:
string[] p = Directory.GetFiles(textBoxDir.Text, listBox1.SelectedItem.ToString(), SearchOption.AllDirectories);
I had a similar problem. This is the shortest way i fixed it.
private void button1_Click(object sender, EventArgs e)
{
radioButton1.Checked = !radioButton1.Checked;
string indicadorPais = "Something";
if (listaPaises.SelectedItem != null)
{
indicadorPais = listaPaises.SelectedItem.ToString();
label1.Text = indicadorPais;
}
As a sidenote. My condition originally was comparing listaPaises.SelectedItem.ToString() != null. This broke because i was casting null to a string. The code im sending works fine.
However none of these allow you to go back in and re-select from the list box. Still working on that issue - will update.
while (user == null) {
try {
user = this.lstAdministratorName.SelectedItem.ToString();
} catch {
lstAdministratorName.ClearSelected();
return;
}
}
Related
I am trying to open any selected textfile and have the text input be sent to a listbox... Originally I wrote this code for a textbox which worked great now that I am converting it to a listbox it doesnt seem to work so much. I left the default item names in order for better understanding of what is going on.
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
label1.Text = openFileDialog1.FileName;
listBox1.Items.Add = File.ReadAllText(label1.Text);
}
}
listBox1.Items.AddRange(File.ReadAllLines(label1.Text));
Try this :
listBox1.Items.AddRange(File.ReadLines(label1.Text).ToArray());
.Add() is a method and you are treating it like a property.
Try this code instead:
listBox1.Items.Add(File.ReadAllText(label1.text));
string[] lines = File.ReadLines("SomeFile.txt").ToArray();
foreach (var line in lines)
{
listBox1.Items.Add(line);
}
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
label1.Text = openFileDialog1.FileName;
//till here the same
//open filestream
System.IO.StreamReader file = new System.IO.StreamReader(openFileDialog1.FileName);
//loop trough lines
while ((line = file.ReadLine()) != null)
{
//add line to listbox
listBox1.Items.Add ( line);
}
}
}
Ok so I have tried a few things and keep getting stuck. I had the update button working at one point and now it will not update. The delete button will work and delete records but I can not get the gridview to refresh after the record is deleted. I also want the gridview to reload after the update button is pressed and the record is updated. Here is what I have:
protected void btnDelete_Click(object sender, EventArgs e)
{
switch (btnDelete.Text)
{
case DeleteButton:
try
{
if (txtLocationName.Text != null && txtSubAccountName.Text != null)
{
Location locationCheck = _context.Locations.ToList()
.First(x => x.Name == txtLocationName.Text && x.SubAccount == txtSubAccountName.Text);
if (locationCheck != null)
{
Location n = new Location
{
Id = grdvwLocationList.SelectedIndex,
Name = txtLocationName.Text,
SubAccount = txtSubAccountName.Text
};
_context.Locations.Remove(n);
_context.SaveChanges();
}
}
}
catch (Exception)
{
lblLocationNameNotification.Text = "Please type in a location/sub-account or select a location/sub-account that doesn't have a asset to delete.";
txtLocationName.Text = "";
txtSubAccountName.Text = "";
}
break;
case CancelButton:
Reload();
break;
}
}
public void PopulateLocationGridView()
{
var locations = _context.Locations.Where(l => l.CompanyId == CompanyId)
.OrderBy(l => l.Name)
.ToList();
grdvwLocationList.DataSource = locations;
grdvwLocationList.DataBind();
if (locations.Count > 0)
{
grdvwLocationList.SelectedIndex = 0;
RowSelected();
}
else
{
txtLocationName.Text = "";
txtSubAccountName.Text = "";
}
}
The add button works just fine it just seems to be refreshing the grid view
I have the following exampe working in a winforms application
The trick is the dset.local
private void Form1_Load(object sender, EventArgs e)
{
var dset = Db.Tasks; // Db is my context.
DbSet<Task> qry = dset;
qry.Load();
bindingSource1.DataSource =dset.Local.ToBindingList();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Debug.Print(Db.Tasks.Count().ToString());
bindingSource1.EndEdit();
Db.SaveChanges();
}
After working on it last night I knew there was something that I was missing. I ended up going about it like this:
protected void btnDelete_Click(object sender, EventArgs e)
{
try
{
_context = new IMSDBContext();
switch (btnDelete.Text)
{
case DeleteButton:
if (txtLocationName.Text != null && txtSubAccountName.Text != null)
{
Location location = _context.Locations.ToList()
.First(x => x.Name == txtLocationName.Text && x.SubAccount == txtSubAccountName.Text);
_context.Locations.Remove(location);
_context.SaveChanges();
PopulateLocationGridView();
grdvwLocationList.SelectedIndex = 0;
RowSelected();
}
break;
case CancelButton:
Reload();
break;
}
}
catch (Exception ex)
{
lblLocationNameNotification.Text = ex.Message;
}
finally
{
if (_context != null)
{
_context.Dispose();
}
}
}
I had tried to use the PopulateLocationGridView() and RowSelect() methods by themselves and it was still having trouble. I ended up putting in the grdvwLocationList.SelectedIndex = 0; in to set the selected index on the first index in the list instead of the index of the record that I just deleted. That is where I was having trouble. I thought that the SelectRow() would reselect the index again but I had to reset it back to another index. If there are any questions or comments please feel free. I am still learning and would like all of the advise that I can get.
I want to update an existing record. I also have debugged my code. The int id variable gets the value, but I don't know why my record doesn't updated.
SQLDBDataClassesDataContext dContext = new SQLDBDataClassesDataContext();
protected void Page_Load(object sender, EventArgs e)
{
//if (!IsPostBack)
{
if (!string.IsNullOrEmpty(Request.QueryString["fname"]))
{
FirstNameTextBox.Text = Request.QueryString["fname"];
}
if (!string.IsNullOrEmpty(Request.QueryString["lname"]))
{
LastNameTextBox.Text = Request.QueryString["lname"];
}
if (!string.IsNullOrEmpty(Request.QueryString["cellnum"]))
{
CellNumberTextBox.Text = Request.QueryString["cellnum"];
}
}
}
protected void UpdateButton_Click(object sender, EventArgs e)
{
int id = Convert.ToInt32(Request.QueryString["id"]);
var updatequery1 = dContext.PersonalDetailTables
.Where(pd => pd.ID == id).SingleOrDefault();
if (updatequery1 != null)
{
updatequery1.FirstName = FirstNameTextBox.Text;
updatequery1.LastName = LastNameTextBox.Text;
updatequery1.CellNumber = CellNumberTextBox.Text;
dContext.SubmitChanges();
}
}
if (updatequery1 != null)
is updatequery1 null? If it's now, it'll just skip right over. Setup a breakpoint and step through.
Alternatively, change .SingleOrDefautl to .Single instead. This way if nothing's found, u'll get an exception, and u'll know what's up.
Call dContext.InsertOnSubmit(fooentity) method before calling dContext.SubmitChanges();.
For example.
var ctx = DB.fooDB;
fooobj.fooName= bar.fooName;
fooobj.fooID= bar.fooID;
if (fooobj.fooID== 0)
ctx.Locations.InsertOnSubmit(bar);
ctx.SubmitChanges();
I`ve got my Solution..
the only problem was of if(!ispostback) issue.
context.InvProductStockMasters
.Update(ps => ps.LocationID.Equals(invStockAdjustmentHeader.LocationID)
&& ps.ProductID.Equals(invStockAdjustmentDetail.ProductID),
ps => new InvProductStockMaster
{ Stock = ps.Stock - invStockAdjustmentDetail.OrderQty });
I have a problem, that I can't solve.
I am writing an application that will help to change system proxy easily. It has a listView with some items. These items have checkboxes.
Logic of application demands that only one item can be checked at a time, so I have following code to make sure it works well:
private void listView1_ItemChecked(object sender, ItemCheckedEventArgs e)
{
listView1.ItemChecked -= listView1_ItemChecked;
foreach(ListViewItem item in listView1.Items)
{
if(item != e.Item)
{
item.Checked = false;
}
}
listView1.ItemChecked += listView1_ItemChecked;
}
Also my application needs to check some value in registry on it's start and compare it's text with my items in listView.
I am doing it like that:
private void GetProxyFromRegistry()
{
RegistryKey SystemProxy = Registry.CurrentUser.CreateSubKey(#"Software\Microsoft\Windows\CurrentVersion\Internet Settings");
try
{
string UsedProxy = SystemProxy.GetValue("ProxyServer").ToString();
foreach (ListViewItem item in listView1.Items)
{
if (UsedProxy == item.Text + ":" + item.SubItems[1].Text)
{
item.Checked = true;
}
else
{
item.Checked = false;
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
The problem is that none of the listView1.Items will be checked except last one when used.
I know that it's because of listView1_ItemChecked(), but I do not know how to solve it the other way.
Can you help me find a solution how to either uncheck all other checkboxes, or find a workaround to make correct item be checked?
this may be a bit of a simple solution to only have one checkbox used at a time, but it works for me. create a listview.click event and then do the following:
private void listView_Click(object sender, System.EventArgs e)
{
foreach (ListViewItem item in listView.Items)
{
item.Checked = false;
}
}
Bit of a hack really, but works great.
So starting with your ItemCheck event, it should be like this:
void listView1_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (e.currentValue == CheckState.Checked)
return;
foreach (ListViewItem item in listView1.Items)
{
if (item.Index != e.Index)
{
item.Checked = false;
}
}
}
For the next issue, I'd suggest setting a breakpoint at this line of code here:
if (UsedProxy == item.Text + ":" + item.SubItems[1].Text)
When the breakpoint is hit (on the last index), check to see what's different about that item in comparison to the others (look at case sensitivity, for instance).
I remember in vb6 there was a control that was similar to a dropbox/combobox that you can select the drive name. It raises an event which you can then set another control which enumerate files in listbox. (in drive.event you do files.path = drive.path to get this affect).
Is there anything like this in C#? a control that drops down a list of available drives and raises an event when it is changed?
There's no built-in control to do that, but it's very easy to accomplish with a standard ComboBox. Drop one on your form, change its DropDownStyle to DropDownList to prevent editing, and in the Load event for the form, add this line:
comboBox1.DataSource = Environment.GetLogicalDrives();
Now you can handle the SelectedValueChanged event to take action when someone changes the selected drive.
After answering this question, I've found another (better?) way to do this. You can use the DriveInfo.GetDrives() method to enumerate the drives and bind the result to the ComboBox. That way you can limit which drives apppear. So you could start with this:
comboBox1.DataSource = System.IO.DriveInfo.GetDrives();
comboBox1.DisplayMember = "Name";
Now comboBox1.SelectedValue will be of type DriveInfo, so you'll get lots more info about the selected game. And if you only want to show network drives, you can do this now:
comboBox1.DataSource = System.IO.DriveInfo.GetDrives()
.Where(d => d.DriveType == System.IO.DriveType.Network);
comboBox1.DisplayMember = "Name";
I think the DriveInfo method is a lot more flexible.
While Matt Hamiltons answer was very correct, I'm wondering if the question itself is. Because, why would you want such a control? It feels very Windows 95 to be honest. Please have a look at the Windows User Experience Interaction Guidelines: http://msdn.microsoft.com/en-us/library/aa511258.aspx
Especially the section about common dialogs:
http://msdn.microsoft.com/en-us/library/aa511274.aspx
I would approach this with:
foreach (var Drives in Environment.GetLogicalDrives())
{
DriveInfo DriveInf = new DriveInfo(Drives);
if (DriveInf.IsReady == true)
{
comboBox1.Items.Add(DriveInf.Name);
}
}
With the help of Drive.IsReady u can avoid having DeviceNotReady or DeviceUnavailable issues.
Bonus:
Also here is a simple "ChooseFile" example which includes a ComboBox for drives, a TreeView for folders and the last a ListBox for files.
namespace ChosenFile
{
public partial class Form1 : Form
{
// Form1 FormLoad
//
public Form1()
{
InitializeComponent();
foreach (var Drives in Environment.GetLogicalDrives())
{
DriveInfo DriveInf = new DriveInfo(Drives);
if (DriveInf.IsReady == true)
{
comboBox1.Items.Add(DriveInf.Name);
}
}
}
// ComboBox1 (Drives)
//
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedItem != null)
{
ListDirectory(treeView1, comboBox1.SelectedItem.ToString());
}
}
// ListDirectory Function (Recursive Approach):
//
private void ListDirectory(TreeView treeView, string path)
{
treeView.Nodes.Clear();
var rootDirectoryInfo = new DirectoryInfo(path);
treeView.Nodes.Add(CreateDirectoryNode(rootDirectoryInfo));
}
// Create Directory Node
//
private static TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
var directoryNode = new TreeNode(directoryInfo.Name);
try
{
foreach (var directory in directoryInfo.GetDirectories())
directoryNode.Nodes.Add(CreateDirectoryNode(directory));
}
catch (Exception ex)
{
UnauthorizedAccessException Uaex = new UnauthorizedAccessException();
if (ex == Uaex)
{
MessageBox.Show(Uaex.Message);
}
}
return directoryNode;
}
// TreeView
//
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
listBox1.Items.Clear();
listBox1.Refresh();
PopulateListBox(listBox1, treeView1.SelectedNode.FullPath.ToString(), "*.pdf");
}
// PopulateListBox Function
//
private void PopulateListBox(ListBox lsb, string Folder, string FileType)
{
try
{
DirectoryInfo dinfo = new DirectoryInfo(Folder);
FileInfo[] Files = dinfo.GetFiles(FileType);
foreach (FileInfo file in Files)
{
lsb.Items.Add(file.Name);
}
}
catch (Exception ex)
{
MessageBox.Show("An error occurred while attempting to load the file. The error is:"
+ System.Environment.NewLine + ex.ToString() + System.Environment.NewLine);
}
}
// ListBox1
//
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox1.SelectedItem != null)
{
//do smt here!
MessageBox.Show(listBox1.SelectedItem.ToString());
}
}
}
}
Just like the old times in VB6.
A comboBox and this little code will do the job. Kindest regards! Luis:
comboBox1.DataSource = System.IO.DriveInfo.GetDrives()
.Where(d => d.DriveType == System.IO.DriveType.Network).ToList();
comboBox1.DisplayMember = "Name";