How to make a MenuStrip with a custom check button? [duplicate] - c#

I'm a beginner in C# language, so I need some help from the geniuses with this scheme: I need to add a radio button for a menu strip. I've already changed the, CheckOnClick property to true, but I need an option for radio button selection. You can see it from the Windows calculator menu bar (click View).
How can I get to it via the MenuStrip property?

I know this is a near-ancient post, but I thought it worth mentioning that although there's no native support for a RadioButton MenueItem, it's easy enough to coax their checkboxes into behaving that way. Start by setting the CheckOnClick property of each MenueItem to FALSE. Then apply the same MouseDown event handler to each item:
private void ToolStripMenueItem_MouseDown(object sender, MouseEventArgs e)
{
var thisTsmi = (ToolStripMenuItem)sender;
foreach (ToolStripMenuItem tsmi in thisTsmi.GetCurrentParent().Items)
{
tsmi.Checked = thisTsmi == tsmi;
}
}
You could use the Click event instead, but I prefer MouseDown because it provides some visualization to the user that the checked item has changed while leaving the Click event open for coding the individual items if needed.

If you navigate to
msdn.microsoft.com/en-us/library/ms404318.aspx
you will see how it's done ;)!

Related

Preventing user selection but allowing selection programmatically

I have a listview control in my windows application, which is populated with some set of items. I will make the selection of an item programmatically by setting ListViewItem.Selected property to true. But I want to prevent the user from selecting an item in the listview. i.e., it should be always selected programmatically. I can prevent the user selection by disabling the control, but disabling the control will also disable the scroll bars which is not correct.
Even I have created a custom listview control and implemented a ItemSelectionChanging eventhandler using WndProc check link, using which i can cancel the event as shown below,
private void lstLiveTables_ItemSelectionChanging(object sender, ListViewExItemSelectionChangingEventArgs e)
{
e.Cancel = true;
}
But again, this will cancel the event, even for an item selected programmatically. My question, is there anyway to identify whether the selection is made manually (by user) or programmatically in SelectedIndexChanged or using WndProc Message.
Note: If it is required, I will upload the code of CustomListView control.
Update 1
Thanks emartel. It was a good thought. Even I tried to achieve the same thing by subscribing to the event only before selecting the item and removed it immediately after selecting. By this way, upon selection the event will be immediately triggered and it will continue. This is working fine.
this.lstTables.SelectedIndexChanged += new System.EventHandler(this.lstTables_SelectedIndexChanged);
item.Selected = true;
this.lstTables.SelectedIndexChanged -= new System.EventHandler(this.lstTables_SelectedIndexChanged);
But again I have a problem that, if the user selects an item manually, nothing will happen (no event will be triggered) but the item alone will be highlighted. Once an item is highlighted and if i try to select the same item programmatically nothing is happening i.e., the SelectedIndexChanged event is not getting triggered for that item as it is already highlighted.
Note: Same behavior even if I follow the Flag approach suggested by you.
Update 2
I can solve this issue by having my own method instead of handling through events as emartel's suggestion. But my question is, according to my update 1, is there anyway to trigger the SelectedIndexChanged event when the item is highlighted but not actually selected?
public FrmTest()
{
list.ItemSelectionChanged += list_ItemSelectionChanged;
}
private bool changing;
private void list_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
if (changing)
return;
if (e.Item == nonSelectableListItem)
{
changing = true;
nonSelectableListItem.Selected = false;
changing = false;
}
}
Sample:
Well, an easy solution would be to keep a flag saying that you are programmatically changing the selection and to allow the event to pass, and reset the flag when you're done
Edit: if you, and only you, can change the selection, and you do this programmatically, so you have control over where and when this happens, why do you even need the EventHandler? Why not call a method to do whatever processing you want to happen?
One dirty way to do that is to keep list of selected items and refresh selection every time it changes other way than from your code.
There is also an ItemSelectionChanged event which is raised separately for every item whose selection state have changed. You can probably flip the selection state back it this event.
You may also take a look on Better ListView Express control. It have a read-only mode, so that user cannot change the selection. Its setup is very simple:
listView.ReadOnly = true;
The full version also supports custom non-selectable items. Simply setting:
listView.Items[0].Selectable = false;
make the first non-selectable (by the user).
You can still select items from code, of course.
The following image shows non-selectable items in action (they are marked by gray color):

WinForm - TabStop Not Working

I have a WinForm with 3 group boxes, one with combo boxes, and two with radio buttons. I set all of them and their children controls to "TabStop = false", but when I cycle with TAB, the currently selected radio button in each of the last two group boxes gets focused.
If there's no way to change this behavior, what would be a good event to catch and move the focus away? I can't find an "OnFocus" event.
The solution is to set one method (code below) to handle the "Enter" event of every radio button in the form (if that's what you wish).
Actually, I only did it for the radio buttons of the first group box and it worked, the second group box's radio buttons don't get focus, even though their "Enter" events are not handled. This is not the behavior you would have expected.
private void radiobuttonXGroup1_Enter(object sender, EventArgs e)
{
SomeOtherControl.Focus();
}
In the *.Designer.cs file you edit every Enter event (for each radio button) to point to one event handler (the above method).
this.radiobutton1Group1.Enter += new System.EventHandler(this.radiobuttonXGroup1_Enter);
this.radiobutton2Group1.Enter += new System.EventHandler(this.radiobuttonXGroup1_Enter);
this.radiobutton3Group1.Enter += new System.EventHandler(this.radiobuttonXGroup1_Enter);
Setting the TabStop to False on a RadioButton to prevent tabbing to the control works until you actully select the radio button without any additional overrides like suggested by #msergeant.
EDIT
The following code prevents the code from getting a tab key event:
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
radioButton1.TabStop = false;
}
Radio buttons behave differently with respect to Tab from other controls in that they work in sets or groups based on setting the tab index or placing then radio buttons in a group box.
The MSDN documentation for RadioButton.TabStop states "This API supports the .NET Framework infrastructure and is not intended to be used directly from your code". Which basically means, "This isn't going to work how you expect it to".
With that said, the Enter event will fire when the button receives the focus. You can try to use that to move focus to another control.

C# Help For Adding Radio Button / Options Button For MenuStrip

I'm a beginner in C# language, so I need some help from the geniuses with this scheme: I need to add a radio button for a menu strip. I've already changed the, CheckOnClick property to true, but I need an option for radio button selection. You can see it from the Windows calculator menu bar (click View).
How can I get to it via the MenuStrip property?
I know this is a near-ancient post, but I thought it worth mentioning that although there's no native support for a RadioButton MenueItem, it's easy enough to coax their checkboxes into behaving that way. Start by setting the CheckOnClick property of each MenueItem to FALSE. Then apply the same MouseDown event handler to each item:
private void ToolStripMenueItem_MouseDown(object sender, MouseEventArgs e)
{
var thisTsmi = (ToolStripMenuItem)sender;
foreach (ToolStripMenuItem tsmi in thisTsmi.GetCurrentParent().Items)
{
tsmi.Checked = thisTsmi == tsmi;
}
}
You could use the Click event instead, but I prefer MouseDown because it provides some visualization to the user that the checked item has changed while leaving the Click event open for coding the individual items if needed.
If you navigate to
msdn.microsoft.com/en-us/library/ms404318.aspx
you will see how it's done ;)!

Adding a right click / context menu to listbox items in C#

I have a ListBox, and its populated with items, id like to know how to:
when you rightclick in the listbox, that the rightclicked item will be selected,
a rightclick menu will be displayed with several items..
when you click on any of the items, a corresponding void will be triggered..
thanks in advance for any help, and code examples please!
This feels to me like a "homework" question, so I am going to answer by (I hope) giving you just a few pointers to solving this for yourself.
Phase One
create a sample project with a ListBox
define event handlers for MouseClick, MouseDown, and Click events.
put a Console.WriteLine("some appropriate text"); statement in each of those handlers so you can look in the Output Window in Visual Studio and see which event handler was called.
...
Phase Two
run the test program and observe the difference between what events are reported for a left mouse down and a right-mouse down (assuming your environment has the context click set to the right mouse down ... which may not be true for everyone).
focus on the one event you can intercept with a context-click.
add a context menu to the test project and set that context menu to be the context menu of the ListBox.
verify that you can now right click on an item in the ListBox and that the context menu will appear, BUT THE EVENT IS STILL HANDLED BY THE HANDLER YOU "DISCOVERED" IN STEP 2.
now go through all the Event handlers for ListBox, and figure out which one could be used to detect, given a certain location in the ListBox, which List Item was "hit."
once you can determine which List Item was right-clicked on, and you know your context menu is working, you have only the problem of making sure that the right-clicked List Item is selected : and that's pretty easy.
Figuring this out yourself will teach you several very useful things you'll be able to use later in programming to other controls.
best of luck, Bill
First, you need to subscribe to ListBox.MouseClick event. You will be able do determine what button was pressed and cursor coordinates. Then, use ListBox.IndexFromPoint method to find clicked item. You can select it using ListBox.SelectedIndex property. To display context menu use ContextMenu or ContextMenuStrip classes. Additional documentation on context menu is available in MSDN
1.when you right click in the listbox, that the right clicked item will be selected
2.a right click menu will be displayed with several items..
private void listBoxNode_MouseUp(object sender, MouseEventArgs e)
{
int location = listBoxNode.IndexFromPoint(e.Location);
if (e.Button == MouseButtons.Right)
{
listBoxNode.SelectedIndex = location; //Index selected
contextMenuStrip1.Show(PointToScreen(e.Location)); //Show Menu
}
}
3.when you click on any of the items, a corresponding void will be triggered..
private void showDetailsToolStripMenuItem_Click(object sender, EventArgs e)
{
//put your code here after clicking
//on items in context menu
}

Best way to swap two .NET controls based on radio buttons

I've got a form where I have two radio buttons and two interchangeable controls (made up of a ListView and a handful of buttons). Based on which radio button is selected I want to display the proper control to the user.
The way I'm doing this now is just loading both controls and setting up an OnRadioButtonSelectionChanged() method which gets called at form load (to set the initial state) and at any time the selection is changed. This method just sets the visible property on each control to the proper value.
This seems to work well enough, but I was curious as to if there was a better or more common way of doing it?
Yep, that's pretty much how I do it. I would set the CheckedChanged event of both radio buttons to point at a single event handler and would place the following code to swap out the visible control.
private void OnRadioButtonCheckedChanged(object sender, EventArgs e)
{
Control1.Visible = RadioButton1.Checked;
Control2.Visible = RadioButton2.Checked;
}
Well you could also use databinding... seems a bit more elegant to me. Suppose you have two radiobuttons "rbA" and "rbB" and two textboxes "txtA" and "txtB". And you want to have txtA visible only when rbA is checked and txtB visible only when rbB is checked. You could do it like so :
private void Form1_Load(object sender, EventArgs e)
{
txtA.DataBindings.Add("Visible", rbA, "Checked");
txtB.DataBindings.Add("Visible", rbB, "Checked");
}
However... I observed that using UserControls instead of TextBoxes breaks the functionality and I should go read on the net why..
LATER EDIT :
The databinding works two-ways! : If you programatically set (from somewhere else) the visibility of the txtA to false the rbA will become unchecked. That's the beauty of Databinding.

Categories