I'm still working on getting a menu to display all of the input devices on a computer- pardon my third question in something that is probably very simple.
Here's the code:
List<MenuItem> inputDevice = new List<MenuItem>();
MenuItem myMenuItemInputDevices = new MenuItem("&Input Devices");
sgFileMenu.MenuItems.Add(myMenuItemInputDevice);
for (int i = 0; i < DeviceCount; i++)
{
inputDeviceMenu.Add(new MenuItem(inputName[i]));
myMenuItemInputDevices.MenuItems.Add(inputDeviceMenu[i]);
myMenuItemInputDevices.Click += new System.EventHandler(this.myMenuItemInputDeviceClick);
}
This seems to work just fine, the menu items are added, everything is good, but clicks on the dropdown list are not working. I've done other work with menus, and clicks in other code are working correctly. I tried putting
myMenuItemInputDevices.Click += new System.EventHandler(this.myMenuItemInputDeviceClick);
outside of the {}, just in case that was the right way to do it, but that didn't help.
What am I missing?
You want this
List<MenuItem> inputDevice = new List<MenuItem>();
MenuItem myMenuItemInputDevices = new MenuItem("&Input Devices");
sgFileMenu.MenuItems.Add(myMenuItemInputDevice);
for (int i = 0; i < DeviceCount; i++)
{
inputDeviceMenu.Add(new MenuItem(inputName[i]));
inputDeviceMenu[i].Click += new System.EventHandler(this.myMenuItemInputDeviceClick);
myMenuItemInputDevices.MenuItems.Add(inputDeviceMenu[i]);
myMenuItemInputDevices.Click += new System.EventHandler(this.myMenuItemInputDeviceClick);
}
EDIT: It is pretty obvious that the Menu Items that you are trying to add does not have any Click event method hooked up.
inputDeviceMenu.Add(new MenuItem(inputName[i]));
You are just adding them.
Related
As I was trying to learn how to use multiple windows in WPF, I stumbled upon a problem. I have a MainWindow containing all the logic for a blackjack game. Now I wanted a second Window with the last 10 games played by the user.
These last 10 games were stored in
public static ListBoxItem[] historiekArray = new ListBoxItem[10];
In the 'Speler' class (Player in Dutch). Now when I try to populate the HistoryWindow Listbox, everything goes well the first time, but the second time I open up the window this error occurs:
System.InvalidOperationException: 'Element already has a logical parent. It must be detached from the old parent before it is attached to a new one.'
This is the C# code in the HistoryWindow.xaml.cs
public HistoriekWindow()
{
InitializeComponent();
// empty the listbox
LbxHistoriek.Items.Clear();
// Populate listbox with array items
for (int i = 0; i < Speler.historiekArray.Length - 1; i++)
{
ListBoxItem temp = new ListBoxItem();
temp = Speler.historiekArray[i];
LbxHistoriek.Items.Add(temp);
}
}
Looking at other posts on StackOverflow and learn.microsoft, I thought the problem might be that my ListBoxItem was being reused, but after placing ListboxItem temp = new ListboxItem() inside the for-loop, nothing much changed.
SOLUTION
The array of ListboxItems was changed into an Array of strings.
public static string[] historiekArray = new string[10];
And the for-loop sets the .Content of the ListBoxItem to the corresponding Array item.
for (int i = 0; i < Speler.historiekArray.Length - 1; i++)
{
ListBoxItem temp = new ListBoxItem();
temp.Content = Speler.historiekArray[i];
LbxHistoriek.Items.Add(temp);
}
Please excuse my formatting, this is my first post on StackOverflow and English is not my native language.
I have a ToolStripMenuItem I need to check if it has a sub menu with a particular name, if it exists, add a new menu item to that sub menu, and if not, create the sub menu and add the item to the new sub menu.
ToolStripItemCollection menu = tsmi1.DropDownItems;
for(int i = 0; i < menu.Count; i++) {
if(item.Category.Equals(menu[i].Text)) {
menu[i]. //need to add new menu item here....
}
}
It may just be that I don't understand how the menu system actually works, but it appears I can't add an item to my menu object.
Is your sub-menu a ToolStripDropDownItem?
The objects in TooLStripItemCollection are all of type ToolStripItem. You may need to cast the item you find to the derived class, ToolStripDropDownItem.
That will give you access to its DropDownItems collection, which is another ToolStripItemCollection and has Add, AddRange, and Insert methods.
I haven't worked with ToolStripDropDownItem myself, but that's the path I'd start on.
Edit by bwoogie:
Final code:
ToolStripMenuItem tsmi = new ToolStripMenuItem();
tsmi.Text = item.Name;
tsmi.Click += node_Click;
ToolStripItemCollection nodeMenu = nodesToolStripMenuItem.DropDownItems;
for (int i = 0; i < nodeMenu.Count; i++) {
if (item.Category.Equals(nodeMenu[i].Text)) {
((ToolStripMenuItem)nodeMenu[i]).DropDownItems.Add(tsmi);
} else {
ToolStripItem newtsi = nodeMenu.Add(item.Category);
((ToolStripMenuItem)newtsi).DropDownItems.Add(tsmi);
}
}
So I found this very puzzling problem which involves dynamic buttons.
Here is my method that creates the buttons:
private void CreateButtons()
{
//Button outside loop works
Button selectItem = new Button();
selectItem.Text = "Hello World";
selectItem.ID = "btn";
selectItem.Click += selectItem_Click;
PlaceHolder1.Controls.Add(selectItem);
int ItemCounter = 0;
for (int i = 0; i < BillDate.Count; i++)
{ //Button inside loop doesnt work
ItemCounter++;
Button selectItem = new Button();
selectItem.Text = "Hello World";
selectItem.ID = "btn-" + ItemCounter.ToString();
selectItem.Click += selectItem_Click;
PlaceHolder1.Controls.Add(selectItem);
}
}
Now here is the problem,
the button that is created outside the loop works fine (event handler selectItem_Click only redirects page).
Why does the button not work inside the loop and why does it work outside the loop?
All of the buttons in your loop have the same ID, since you're not incrementing ItemCounter. While you could just use i instead, you don't appear to be using the ID at all, so you're better off just not setting it in the first place.
Also keep in mind that on the post back the buttons need to be created and added to the page in the PreInit event in order for the event handler to be able to run.
Dynamically creating controls, particularly controls that have handlers on subsequent postbacks, can be quite tricky. It's not uncommon at all to need data from the request to be able to generate the controls, but to need the controls to be generated before the request is processed by ASP for the events to fire. It's dramatically easier to create a template that you bind your data to, using something like a GridView or a Repeater instead, as it will be able to properly handle re-creating the controls before the request is processed while still allowing you to have a dynamic number of instances of the template.
**Use the below code it will work.**
private void CreateButtons()
{
//Button outside loop works
Button selectItem = new Button();
selectItem.Text = "Hello World";
selectItem.ID = "btn";
selectItem.Click += selectItem_Click;
PlaceHolder1.Controls.Add(selectItem);
int ItemCounter = 0;
for (int i = 0; i < BillDate.Count; i++)
{ //Button inside loop doesnt work
Button selectItem = new Button();
selectItem.Text = "Hello World";
selectItem.ID = "btn-" + ItemCounter.ToString();
selectItem.Click += selectItem_Click;
ItemCounter++;
PlaceHolder1.Controls.Add(selectItem);
}
}
I have a list of CheckBoxes and after clicking on them the state is not updated.
Why is this happening and how can I repair this?
private List<CheckBox> blocks_check_boxes = new List<CheckBox>();
count = blocks_from_database.Count;
/* Display check boxes for each block*/
for (int i = 0; i < blocks_from_database.Count; i++)
{
blocks_check_boxes.Add(new CheckBox());
this.blocks_check_boxes[i].AutoSize = true;
this.blocks_check_boxes[i].Name = blocks_from_database[i].name;
this.blocks_check_boxes[i].Size = new System.Drawing.Size(80, 17);
this.blocks_check_boxes[i].TabIndex = 3 + i;
this.blocks_check_boxes[i].Text = blocks_from_database[i].name;
this.blocks_check_boxes[i].UseVisualStyleBackColor = true;
this.blocks_check_boxes[i].AutoCheck = true;
}
Thank you
Maybe you are recreating the CheckBoxes in an unwanted way.
Maybe you want to set the "AutoPostBack" property till "true".
It's pretty hard to understand what's causing your problem when we don't see more code. Explain a little more when you are detecting your problem and also where and when your code above is executing.
*Hi everyone,
I'm new in WP7 dev. (i'm used to work on android) and there is a basic thing i don't know how to do.
I create programmatically a list of ApplicationBarIconButton with this:
for (int i=0; i<menus.Count(); i++)
{
ApplicationBarIconButton button = new ApplicationBarIconButton();
button.IconUri = new Uri(menus.ElementAt(i).Element("ImageUrl").Value.Trim(),UriKind.Relative);
button.Text = menus.ElementAt(i).Element("Title").Value.Trim();
button.Click += new EventHandler(button_clicked);
ApplicationBar.Buttons.Add(button);
}
and I want that the button_clicked method could retrieve the i value of the button.
How is it possible?
Thanks
I was beaten to it by #Enigmativity but his answer may still be incorrect. In my experience I've found that you need to clone the iterating i variable, otherwise on the click event, i will be the last value. If his doesn't work try this (again using a lamba function)
for (int i=0; i<menus.Count(); i++){
ApplicationBarIconButton button = new ...
...
var cloned = i;
button.Click += (sender, e) => {
sometTextBlock.Text = String.Format("App Button {0} pressed.", cloned);
};
}
Cheers,
Al.
You could do this:
for (int i=0; i<menus.Count(); i++)
{
ApplicationBarIconButton button = new ApplicationBarIconButton();
button.IconUri = new Uri(menus.ElementAt(i).Element("ImageUrl").Value.Trim(),UriKind.Relative);
button.Text = menus.ElementAt(i).Element("Title").Value.Trim();
var i2 = i; //Thanks to `ajmccall` - I forgot this.
button.Click += (s, e) =>
{
// the variable `i2` is accessible now.
};
ApplicationBar.Buttons.Add(button);
}
Rather than calling a method to handle click you can use a lambda and still get access to i (via local copy i2). You could then call any method passing i2 as a parameter if you need to.
An integrated way of achieving this is through the use of commanding in MVVM frameworks.
Granted with Application bar buttons / menu items it is a bit more tricky but far more flexible than to manipulate the UI Elements on the page.
Look in to MVVM light (http://mvvmlight.codeplex.com) or further with the likes of Calburn.Micro (http://caliburnmicro.codeplex.com/)
For application bar data binding you will need to google further (lost the link at the mo)