In C# how can i keep my Treeview node selected upon refresh - c#

I'm really new to coding
I have a treeview that refreshes with a timer.
How can i make sure i keep my selected node highlighted every time it refreshes
Appreciate any help
Thanks
Here is the code that I have:
private void PopulateTree(ListObjectsResponse buckets)
{
treeView1.Nodes.Clear();
List<TreeItem> items = new List<TreeItem>();
foreach (S3Object obj in buckets.S3Objects)
{
treeView1.Nodes.Add(new TreeNode(obj.Key));
}
}
private void button4_Click_1(object sender, EventArgs e)
{
timer1.Enabled = true;
existingBucketName = label3.Text + "-DP";
AmazonS3Client client = new AmazonS3Client();
ListObjectsRequest listRequest = new ListObjectsRequest
{
BucketName = existingBucketName,
};
try
{
ListObjectsResponse listResponse;
listResponse = client.ListObjects(listRequest);
PopulateTree(listResponse);
}
catch
{
timer1.Enabled = false;
MessageBox.Show("There is no folder for this user");
}
}

Assuming that o.Key is a string, and that each string is unique and occurs at most once in buckets.S3Objects, try saving the selected value before repopulating the TreeView, then select it again afterwards.
private void PopulateTree(ListObjectsResponse buckets)
{
// Since you're about to clear out all current TreeNode instances, storing a
// reference to SelectedNode is not enough. You're setting o.Key as the Text
// for each TreeNode, so save the selected node's Text value.
var selectedText
= treeView1.SelectedNode == null ? "" : treeView1.SelectedNode.Text;
// Repopulate your TreeView with new TreeNodes
treeView1.Nodes.Clear();
treeView1.Nodes.AddRange(buckets.S3Objects.Select(o => new TreeNode(o.Key)).ToArray())
// Look for the TreeNode with the same Text that you had selected before.
// If it's not found, then SelectedNode will be set to null
treeView1.SelectedNode =
= treeView1.Nodes.Cast<TreeNode>()
.SingleOrDefault(n => n.Text == selectedText);
}
Several of the above methods, such as Select, Cast, and SingleOrDefault, are part of LINQ.

Assuming this is ASP.NET (not ASP.NET MVC) that you're talking about, you would do this in the Page_Load() event handler. Be sure to check whether IsPostBack == true
For example,
private void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// set selected node here
}
}
If you are using ASP.NET MVC then just store the property in the ViewBag.

Related

List doesn't filter properly using Contains in combobox

I am trying to come up with a solution where I can search items inside a combo box that contain certain word/phrase. I tried using the AutoComplete text box functionality, but that only searches for the first word which is no good to me.
I have followed the example provided at https://social.msdn.microsoft.com/Forums/vstudio/en-US/4c229a73-cdad-4fa3-95db-97f9ff7810c1/autocomplete-match-on-contains-not-startswith?forum=netfxbcl
I have initiated 2 lists
public List<string> listOnit = new List<string>();
public List<string> listNew = new List<string>();
I then load the data into a comboBox
if (rdr.HasRows == true)
{
// var source = new List<string>();
while (rdr.Read())
{
// myCollectionSales.Add(rdr[0].ToString());
listOnit.Add(rdr[0].ToString());
}
rdr.Close();
//textBox1.AutoCompleteCustomSource = myCollectionSales;
comboBox1.Items.AddRange(listOnit.ToArray());
}
and have a TextUpdate event handler to filter the list when text has changed
private void comboBox1_TextUpdate(object sender, EventArgs e)
{
comboBox1.Items.Clear();
listNew.Clear();
foreach (var item in listOnit)
{
if (item.Contains(this.comboBox1.Text))
{
listNew.Add(item);
}
}
comboBox1.Items.AddRange(listNew.ToArray());
comboBox1.SelectionStart = this.comboBox1.Text.Length;
Cursor = Cursors.Default;
comboBox1.DroppedDown = true;
}
I am coming across a problem where the search results don't return what I expect. For example, I search for the string "Bud" and I only get the following results
http://prntscr.com/ppkatd
While in the database, there is also Budweiser 33cl and Keg Budweiser (http://prntscr.com/ppkbu4), for example, which is fetched on the first list.
Should I be using a different method, rather than "Contains"?
Perhaps you are using different cases?
Try with .ToLower():
private void comboBox1_TextUpdate(object sender, EventArgs e)
{
comboBox1.Items.Clear();
listNew.Clear();
foreach (var item in listOnit)
{
if (item.ToLower().Contains(this.comboBox1.Text.ToLower()))
{
listNew.Add(item);
}
}
comboBox1.Items.AddRange(listNew.ToArray());
comboBox1.SelectionStart = this.comboBox1.Text.Length;
Cursor = Cursors.Default;
comboBox1.DroppedDown = true;
}

MenuItem Click event handler not called

I´m building a ContextMenu on the fly, like this
readinstance = null;
ContextMenu cMenu = new ContextMenu();
for (int i = 0; i < instances.Length; i++) {
string text = String.Format("{0} - {1}", instances[i].Id, instances[i].FormName);
MenuItem item = new MenuItem(text, new EventHandler(cMenuitem_Click));
item.Tag = instances[i];
cMenu.MenuItems.Add(item);
}
cMenu.Show((Button)sender, new Point(0, 0));
cMenu.Dispose();
if (readinstance == null)
throw new Exception("Must select some instance");
and the handler is
void cMenuitem_Click(object sender, EventArgs e)
{
MenuItem item = (MenuItem)sender;
readinstance = (FormPrintingStorage)item.Tag;
}
The menu displays correctly, but when I click some of the options, the handler is not called, so readinstance remains null, and the exception throws. As a side note, when I click any of the options, the menu disappears.
I cannot see what is wrong with my code. Any help will be appreciated.
I´m answering my own question, because I tried more ways.
The first one was to replace the ContextMenu with a ListView and an "Ok" button, at no luck, because the wait loop needed a Thread.Sleep. No comments.
The solution was to implement a new dialog with an empty list view an the Ok button. Some of the relevant code follows. Note that only TreeViewItem/s are moved between the main form and the dialog.
ListViewItem _result = null;
public ListViewItem Result { get { return _result; } }
public List<ListViewItem> Source
{
set
{
listView1.Items.Clear();
foreach (ListViewItem item in value)
listView1.Items.Add(item);
listView1.View = View.List;
}
}
private void button1_Click(object sender, EventArgs e)
{
if (_result == null)
return;
DialogResult = DialogResult.OK;
Close();
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
ListView list = (ListView)sender;
ListView.SelectedIndexCollection indices = list.SelectedIndices;
if (indices.Count == 0)
return;
_result = list.Items[indices[0]];
}
Getting the Result, the main form may do anything it wants with the Tag member. In fact, I´m using the same dialog for two different purposes in the same form.

XML nodes editing.

I assign values from a queryString to these textboxes and that works fine , but whenever I edit the text in one of them and try to get the edited data to be saved in XML node, I can't
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString != null)
{
TextBox_firstname.Text = Request.QueryString["column1"];
TextBox_lastname.Text = Request.QueryString["column2"];
}
else
{
}
}
Is there something with this code? It saves the unedited version in the nodes!
public string str_id;
public int id;
id = int.Parse(str_id);
XDocument xdoc = XDocument.Load(filepath);
if (id == 1)
{
var StudentNodeWithID1 = xdoc.Descendants("students")
.Elements("student")
.Where(s => s.Element("id").Value == "1")
.SingleOrDefault();
StudentNodeWithID1.Element("first_name").Value = TextBox_firstname.Text;
StudentNodeWithID1.Element("last_name").Value = TextBox_lastname.Text;
}
Page_Load is fired on every load (on postback as well as on initial load). Your code is currently defaulting those values from Request.QueryString on every load, before your event handler tries to save it.
Do this instead:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack && Request.QueryString != null)
{
TextBox_firstname.Text = Request.QueryString["column1"];
TextBox_lastname.Text = Request.QueryString["column2"];
}
else
{
}
}
If you are submitting the edited textboxes, then you will need to wrap the code in your Pageload with IsPostback check to ensure that values do not get reset to their originals.

How to loop through dropdown items in a toolstrip

I have a dropdown in my toolstrip (toolbar) i have attached a click event to each item in drop down as the dropdown has been populated dynamically, now i can casted the selected item in the dropdown and set its state to checked, to have a tick next to it, i wish to have a loop in another method to check which item has been checked. How do i loop through the items in the dropdown checking which item is checked?
foreach (DataSet1.xspLibraryByNameRow libName in data.xspLibraryByName)
{
var name = new LibraryItems(libName);
if (libName.xlib_Code != "NULL")
{
catDrpDwn.DropDown.Items.Add(name);
catDrpDwn.DropDown.Tag = name;
name.Click += new EventHandler(name_Click);
}
}
}
void mapArea_VE_MapReady(object sender, EventArgs e)
{
loadPoints();
}
void name_Click(object sender, EventArgs e)
{
var selected = (LibraryItems)sender;
selected.Checked = true;
loadPoints();
}
foreach (var items in catDrpDwn.DropDown.Items)
{
var it = (LibraryItems)items;
if (it.Checked == true)
{
}
}
Try this
var items=catDrpDwn.DropDown.Items.Cast<LibraryItems>().Where(d=>d.Checked).ToList();
here you will get all checked items and you can loop into it.

SelectionIndexChanged firing twice

I am wondering why my selection index changed is firing twice when I click on an item on my list.
This is the code I use in the selectionindexchanged
private void listBoxFolders_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Taking the name of the folder to pass in the parameters
if ((Folder)listBoxFolders.SelectedItem != null)
{
folderTmp = (Folder)listBoxFolders.SelectedItem;
}
// Connection to the webservice to get the subfolders and also the files
WebClient wc = new WebClient();
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted2);
wc.DownloadStringAsync(new Uri("http://clients.uicentric.net/IISHostedCalcService/FilesService.svc/GetFoldersAndFiles?selectedFolder=" + folderTmp.Name));
}
and this is the method which is firing twice inside it:
public void wc_DownloadStringCompleted2(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
XDocument xdoc = XDocument.Parse(e.Result, LoadOptions.None);
XNamespace aNamespace = XNamespace.Get("http://schemas.datacontract.org/2004/07/System.IO");
try
{
// Retrieving the subfolders
var folders = from query in xdoc.Descendants(aNamespace.GetName("DirectoryInfo"))
select new Folder
{
Name = (string)query.Element("OriginalPath"),
};
_lFolders = new ObservableCollection<Folder>();
foreach (Folder f in folders)
{
LFolders.Add(f);
}
listBoxFolders.ItemsSource = LFolders;
listBoxFolders.DisplayMemberPath = "Name";
// Retrieving the files
var files = from query in xdoc.Descendants(aNamespace.GetName("FileInfo"))
select new File
{
Name = (string)query.Element("OriginalPath"),
};
_lFiles = new ObservableCollection<File>();
foreach (File f in files)
{
LFiles.Add(f);
}
listBoxFiles.ItemsSource = LFiles;
listBoxFiles.DisplayMemberPath = "Name";
listBoxFiles.SelectionChanged += new SelectionChangedEventHandler(listBoxFiles_SelectionChanged);
}
catch { }
}
}
You are reloading the item source of listbox upon the selection changed event. Becoause of the reload action, the index gets changed to its default value, ie, -1 .
This probably must be your issue.
Instead of using selection changed event go for Tap event.

Categories

Resources