I'm fresher to C#. I have a doubt, please anyone clarify me.
Firstly when i clicked on a button in first form, a new form should be opened with only one tab by default (basically this form will have 3 tabs).
In the default tab i will have a comboBox with list of 2 items. If i have selected a particular item, then the corresponding tab should be appeared beside
the default tab.
I have done everything but i didn't get how to hide the tab other than the default one,and how to show the corresponding tab when an item was selected from combo box. please help me.
Thank you in advance.
A TabControl has multiple TabPages, each of them having a Visible property.
(assuming you are using WinForms)
TabPage has no Visible Property, you have to remove the tab then add it again, here is a simple piece of code:
private void Form1_Load(object sender, EventArgs e)
{
List<int> myList = new List<int>() {1,2,3,4,5 };
listBox1.DataSource = myList;
foreach (var item in tabControl1.TabPages)
{
MyTabPages.Add(item as TabPage);
}
}
List<TabPage> MyTabPages = new List<TabPage>();
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (MyTabPages.Count == 0)
{
return;
}
Int32 Index = listBox1.SelectedIndex;
if (Index >= 0 && Index <= MyTabPages.Count - 1)
{
if(tabControl1.TabPages.IndexOf(MyTabPages[Index]) < 0)
{
tabControl1.TabPages.Add(MyTabPages[Index]);
}
else
{
tabControl1.TabPages.Remove(MyTabPages[Index]);
}
}
}
I Hope this helps.
These methods should help you:
public void ShowTab(TabControl tabs, TabPage page)
{
tabs.TabPages.Add(page)
}
public void HideTab(TabControl tabs, TabPage page)
{
tabs.TabPages.Remove(page)
}
A working example with a tab (tabPage1) as default tab with a comboBox control named comboBox1:
//Temporarly list to keep created tabs
List<TabPage> tempPages = new List<TabPage>();
private void Form2_Load(object sender, EventArgs e)
{
comboBox1.Items.Add("tabPage2");
comboBox1.Items.Add("tabPage3");
}
public void RemoveTabs()
{
//Remove all tabs in tempPages if there are any
if (tempPages != null)
{
foreach (var page in tempPages)
{
tabControl1.TabPages.Remove(page);
}
tempPages.Clear();
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex >= 0)
{
RemoveTabs();
var newTabName = ((ComboBox)sender).SelectedItem.ToString();
var newtab = new TabPage(newTabName);
//Create the new tabPage
tabControl1.TabPages.Add(newtab);
//Add the newly created tab to the tempPages list
tempPages.Add(newtab);
}
}
Related
My task is to create two edit buttons for a listbox, one edit-start button and one edit-end button, with relevant functionality.
The user should be able to edit a selected item on the list box after pressing the edit-start button. the change should then be saved after pressing edit-end.
Thanks for any input on this matter.
If your project is in c# WinForms, i recomended following solution:
Add ListBox (name is MyListBox), Two Buttons(btnBeginEdit and btnEndEdit) and one edit component(MyTextBox) to your form;
In form source you may use like this code:
public Form1()
{
InitializeComponent();
for (var i = 1; i <= 10; i++)
MyListBox.Items.Add($"Item-{i}");
}
private void btnBeginEdit_Click(object sender, EventArgs e)
{
if (MyListBox.SelectedIndex == -1)
{
MessageBox.Show("Please select ListBox item firstly!");
return;
}
var item = MyListBox.SelectedItem.ToString();
MyTextBox.Text = item;
MyListBox.Enabled = false;
}
private void btnEndEdit_Click(object sender, EventArgs e)
{
if (MyListBox.SelectedIndex == -1)
return;
MyListBox.Items[MyListBox.SelectedIndex] = MyTextBox.Text;
MyListBox.Enabled = true;
}
I am trying to re-enable only the listbox that pertains to the item that has been removed from the output listbox. For example, If I select "Wagon" from Body Type listbox and "Advance" from Package listbox, the listbox named "lstOutPut" displays the following:
What I want to do is, if I were to remove "SUV", I would only want for Body Type listbox re-enabled and not the rest
Here is my code
private void lstBody_SelectedIndexChanged(object sender, EventArgs e)
{
if (lstBody.SelectedItem != null)
{
lstOutput.Items.Add(lstBody.SelectedItem);
lstBody.SelectionMode = SelectionMode.None;
lstBody.Enabled = false;
}
}
private void lstPackage_SelectedIndexChanged(object sender, EventArgs e)
{
if (lstPackage.SelectedItem != null)
{
lstOutput.Items.Add(lstPackage.SelectedItem);
lstPackage.SelectionMode = SelectionMode.None;
lstPackage.Enabled = false;
}
}
And this is what I have for the remove button
private void btnRemove_Click(object sender, EventArgs e)
{
//remove selected item only
while (lstOutput.SelectedItems.Count > 0)
{
lstOutput.Items.Remove(lstOutput.SelectedItems[0]);
}
lstBody.Enabled = true;
lstPackage.Enabled = true;
}
Any ideas?
Thanks.
Assuming there would not be duplicates values among the different input listboxes,you could do the following in the btnRemove_Click event
var inputListBoxes = new[] { lstPackage, lstBody };
while (lstOutput.SelectedItems.Count > 0)
{
inputListBoxes.First(x => x.Items.Contains(lstOutput.SelectedItems[0])).Enabled = true;
lstOutput.Items.Remove(lstOutput.SelectedItems[0]);
}
For each listbox, enable it if non of its items exist in lstOutput:
var listBoxes = new ListBox[] {body, package, wheel, accessories};
foreach(var lst in listBoxes)
lst.Enabled = !lst.Items.Cast<string>().Any(x => lstOutput.Items.Contains(x));
I am trying to open a new form by clicking on a row in a ListView and pass the NoteId that is listed in the specific Row to the new Form, can anyone help please?
Sorry if this is a silly question, but I have only been programming since last month and my research proved fruitless :(
private void populatingMainList()
{
List<Note> getAllNotes = GetAllNotes();
lstMain.Items.Clear();
for (int i = 0; i < getAllNotes.Count; i++)
{
lstMain.FullRowSelect = true;
string _note;
ListViewItem lvi = new ListViewItem(_note = getAllNotes[i].NoteComplete.ToString());
if (_note == "True")
{
lvi.Text = "";
lvi.Checked = true;
}
else
{
lvi.Text = "";
lvi.Checked = false;
}
lvi.SubItems.Add(getAllNotes[i].NoteTitle);
lvi.SubItems.Add(getAllNotes[i].NoteDot.ToString("dd-MM-yyyy"));
lvi.SubItems.Add(getAllNotes[i].NoteNote);
lvi.SubItems.Add(getAllNotes[i].NoteId.ToString());
lstMain.Items.Add(lvi);
}
}
private void lstMain_SelectedIndexChanged_1(object sender, EventArgs e)
{
//I believe that some sort of code that retrieve NoteId from the specific Row must be added here.
if (_list == true)
{
frmSticky StickyForm = new frmSticky(_currentUser, _noteid);
}
}
private void lstMain_SelectedIndexChanged_1(object sender, EventArgs e)
{
var lst = sender as ListView;
_noteid = lst.SelectedItems[0].SubItems[3];
if (_list == true)
{
frmSticky StickyForm = new frmSticky(_currentUser, _noteid);
}
}
You can use a contextmenustrip for your listview and then add a button on it with function to open the form you are trying to.
1.Find ContextMenuStrip and add it to your application from toolbox.
2.Add it to your listview as shown in the image below.
3.Select the contextmenu you added and create a new button by clicking on "Type here".
4.Double click that button on your contextmenu and write the code you want to execute when you click on that button on contextmenu from listview.
I have two list box in WPF which looks something like this:
Lets say, the left one is lbLeft and right one is lbRight. The ">" button adds one selected item from lbLeft to lbRight. And, "<" removes the selected item form lbRight from the list. The ">>" adds all the item from lbLeft to lbRight and "<<" clears lbRight.
When I double click an item from lbLeft, it is added to the lbLeft and that newly added item is focused. Also, if i try to add an item from lbLeft which already exists in lbRight, it places a focus in that selected item(so that items are not repeated). But when lots of item are added in lbRight, I have to manually scroll down to the point where focus is placed. How can I make the scrolling of listbox automatic to the point where focus is placed?
I have done the following:
private void select_Click(object sender, RoutedEventArgs e) // > button
{
addingItemToSelectedList();
}
private void remove_Click(object sender, RoutedEventArgs e) // < button
{
if (lbRight.SelectedItem != null) {
lbRight.Items.RemoveAt(lbRight.SelectedIndex);
}
}
private void selectall_Click(object sender, RoutedEventArgs e) // >> button
{
lbRight.Items.Clear();
foreach (string item in column1) {
lbRight.Items.Add(item);
}
}
private void lbLeft_MouseDoubleClick_1(object sender, MouseButtonEventArgs e)
{
addingItemToSelectedList();
}
private void addingItemToSelectedList() {
if (lbLeft.SelectedItem != null)
{
string item = lbLeft.SelectedItem.ToString();
addFocus(item);
}
}
private void addFocus(string item) {
if (!lbRight.Items.Contains(item))
{
lbRight.Items.Add(item);
lbRight.SelectedIndex = lbRight.Items.Count - 1;
lbRight.Focus();
}
else
{
int index = lbRight.Items.IndexOf(item);
lbRight.SelectedIndex = index;
lbRight.Focus();
}
}
private void removeall_Click_1(object sender, RoutedEventArgs e) //<< button
{
lbRight.ItemsSource = null;
lbRight.Items.Clear();
}
column1 in the code is a list of items which populate lbLeft.
UPDATE:
I tried to use lbRight.ScrollIntoView(lbRight.SelectedIndex); But it has no effect
ScrollIntoView() worked now. What i had to do was:
lbRight.ScrollIntoView(lbRight.Items[lbRight.SelectedIndex]);
It now passes the actual item rather than index of it.
I am working on a Visual Studio extension and my current goal is to set up a menu item in the Tools menu. When clicked on this menu item will open a WinForms window containing a ListView, 3 textboxes, and a button. The idea is when you click on one of the rows in the ListView the data from that row will be populated in the textboxes so that you can update it. If you click the button a new row is added and the textboxes are cleared. However, I'm having an issue with getting the index of the row that I've selected.
private int _index;
private void newSourceBtn_Click(object sender, EventArgs e)
{
// Add new row to the ListView
ListViewItem row = new ListViewItem();
row.SubItems.Add("new");
row.SubItems.Add(String.Empty);
row.SubItems.Add(String.Empty);
remoteSourceListView.Items.Add(row);
int index = remoteSourceListView.Items.Count - 1;
remoteSourceListView.Items[index].Selected = true;
newSourceAdded = true;
sourceNameTextBox.Clear();
sourceUrlTextBox.Clear();
}
public void SourceName_TextChanged(object sender, EventArgs e)
{
remoteSourceListView.Items[IndexSelected].SubItems[1].Text = sourceNameTextBox.Text;
}
public void SourceURL_TextChanged(object sender, EventArgs e)
{
string url = sourceUrlTextBox.Text;
if ((url.StartsWith("http")) || (url.StartsWith("https")) || (url.StartsWith("git")))
{
sourceBranchTextBox.Enabled = true;
}
remoteSourceListView.Items[IndexSelected].SubItems[2].Text = url;
}
public void SourceBranch_TextChanged(object sender, EventArgs e)
{
}
public void SourcesListView_SelectedIndexChanged(object sender, EventArgs e)
{
ListView.SelectedListViewItemCollection selectedRows = remoteSourceListView.SelectedItems;
foreach (ListViewItem row in selectedRows)
{
sourceNameTextBox.Text = row.SubItems[1].Text;
sourceUrlTextBox.Text = row.SubItems[2].Text;
IndexSelected = row.Index;
if (row.SubItems[3].Text != "")
{
sourceBranchTextBox.Enabled = true;
sourceBranchTextBox.Text = row.SubItems[3].Text;
}
}
}
public int IndexSelected
{
get { return _index; }
set { _index = value; }
}
This code shows the button click event which adds the new row to the ListView, the text changed events for each of the textboxes which updates the row in the ListView (sorta), and the selected index changed event for the ListView which is where I'm getting the index of the row that was just selected. While debugging, I noticed that when I click on a row I'm getting the correct index in the selected index changed event; however, when I call IndexSelected from either of the text changed events it is always giving me a different index.
Any suggestions?
From the code posted I can't find any reason that explain the behavior documented.
A possible reason could be the insertion/deletion of new/existing ListViewItem in a position before the saved RowIndex.
However another approach is possible. Instead of keeping the RowIndex you could try to set a global property to the ListViewItem selected and reuse this instance when you need to set its subitems.
In this way you avoid problems if the number of ListViewItems change and some item is inserted/removed before the saved RowIndex. However a safeguard against a null value should be provided.
private ListViewItem CurrentItemSelected {get;set;}
......
public void SourcesListView_SelectedIndexChanged(object sender, EventArgs e)
{
ListView.SelectedListViewItemCollection selectedRows = remoteSourceListView.SelectedItems;
foreach (ListViewItem row in selectedRows)
{
sourceNameTextBox.Text = row.SubItems[1].Text;
sourceUrlTextBox.Text = row.SubItems[2].Text;
CurrentItemSelected = row;
if (row.SubItems[3].Text != "")
{
sourceBranchTextBox.Enabled = true;
sourceBranchTextBox.Text = row.SubItems[3].Text;
}
}
}
public void SourceName_TextChanged(object sender, EventArgs e)
{
if(CurrentItemSelected != null)
CurrentItemSelected.SubItems[1].Text = sourceNameTextBox.Text;
}
However, I am a bit perplexed by your code. Do you have the property MultiSelect set to true? Because if it is set to false then your code doesn't need to loop.
public void SourcesListView_SelectedIndexChanged(object sender, EventArgs e)
{
if(remoteSourceListView.SelectedItems.Count > 0)
{
// With MultiSelect = false; there is only one selected item.
CurrentItemSelected = remoteSourceListView.SelectedItems[0];
sourceNameTextBox.Text = CurrentItemSelected.SubItems[1].Text;
sourceUrlTextBox.Text = CurrentItemSelected.SubItems[2].Text;
if (CurrentItemSelected.SubItems[3].Text != "")
{
sourceBranchTextBox.Enabled = true;
sourceBranchTextBox.Text = CurrentItemSelected.SubItems[3].Text;
}
}
}