When i render contextmenustrip, it gets render at the top left of my PC Screen. I have a listview, which contains 5-6 items and on right click of each item, the context Menu strip gets displayed.Also i need to change the color of context menu strip including backgrounds and text as well.
Thanks in advance!
By far the simplest way is to just set the ListView.ContextMenuStrip property to your CMS, everything is automatic then. You can do so in the designer.
If you need a custom handler for some reason, to check if the right item was clicked for example, then you can call the Show() method property with code like this:
private void listView1_MouseClick(object sender, MouseEventArgs e) {
if (allowContextMenu(listView1.SelectedItems) {
contextMenuStrip1.Show(listView1, e.Location);
}
}
You haven't shown any code, but if you're not calling the Show overload that takes a control as a parameter, the new Point(0, 0) that your obviously passing will put the menu in the upper left of the screen.
Related
I'm trying to make it to where a panel becomes visible and it sent to the front so it can be seen and interacted with, like this.
private void SettingsButton_Click(object sender, EventArgs e)
{
SettingsPanel.Visible = true;
SettingsPanel.BringToFront();
}
The problem is that after clicking a few of the buttons, it will either display the wrong panel or none at all. Is there a way to fix this?
EDIT: Before y'all ask, i'm using WinForms.
OK, so I was wrong, WinForms is smarter than I thought. Here's a test you can do. I'm not exactly sure what you are trying to do, but this should help you along. To start, we're going to build a small WinForms app. With one exception, we aren't going to set any properties of the controls we drop on the screen:
Create a new WinForms app
In the designer, drop a Panel (which will be named panel1) on the form
In the properties pane, set the BorderStyle to FixedSingle (that's the only property we are going to set)
Make two copies of that panel (panel2 and panel3). Position them so that panels do not overlap at all.
On each panel drop a couple of controls (I put labels (labels 1-3) and textboxes (also 1-3)) on each one
Beside each panel (arranged so that there is no overlap) drop three buttons on the form (buttons 1-3) make it so that visually, each button is associated with the similarly numbered panel
Duplicate panel3 including its contained controls (so that you get panel4, label4 and textbox4). Position the duplicate so that it significantly overlaps panel 3
Now we're going to look at the code that the designer creates for your form. Don't mess with this code (you can, but if you don't know what you are doing, it can turn out bad - and, we're keeping this simple).
In the Solution Explorer click the unfilled triangle to the left of Form1.cs. Note that it rotates and turns solid. Also note that Form1.Designer.cs is displayed. That's a normally hidden source file that contains all the designer created code that corresponds with the form and the controls you dropped on it.
Open Form1.Designer.cs
Click the little grey plus sign icon next to Windows Form Designer generated code
Inspect the file. Note that every action you did in the designer has a corresponding line of code in the Designer.cs file (more or less)
Look at the code for one of the panels (say panel1).
See that it includes:
this.panel1.Controls.Add(this.textBox1);
this.panel1.Controls.Add(this.label1);
Scroll all the way down to the Form1 code and see that the panels and buttons get added to the Form's Controls collection:
Like:
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.panel4);
this.Controls.Add(this.panel3);
this.Controls.Add(this.panel2);
this.Controls.Add(this.panel1);
Note that the order is reversed. The order is important, it sets the Z-Order (i.e., what overlaps what) for the form and the controls on the form.
Wiring up the buttons
Select all three buttons and press <Enter>. This will open the Form1.cs file and generate three button click handlers that you can fill in.
Use this code for the three button handlers:
private void button1_Click(object sender, EventArgs e) {
var wasVisible = panel1.Visible;
panel1.Visible = !wasVisible;
}
private void button2_Click(object sender, EventArgs e) {
panel2.BringToFront();
}
private void button3_Click(object sender, EventArgs e) {
panel3.BringToFront();
}
The first one will toggle the first panel's visibility (I put in an extra variable so you can set a breakpoint and see what's going on). The second one brings panel2 to the front, changing its Z-Order (it's called Z-Order because the position on the screen is measure in X and Y, which the overlap position is related to the "depth" of the screen, or the Z-coordinate). The last one does the same thing to panel3.
Run the program.
When you press the first button, the first panel and its controls disappear (this surprised me, WinForms is smarter than I thought)
When you press the second button, nothing appears to happen. This is because the only thing that panel2 intersects is the form, and panel2 already covers the form, so you don't see any effect. (and because WinForms is smarter than I thought)
When you press the third button, panel2 (and it's controls) jump to the front of the stack of controls, covering the intersecting part of panel4.
Does this help you understand how Visible and BringToFront() work?
What you're describing is similar to a TabControl alternative. Here's an example:
You can manage the current panel simply by making it visible and docked to fill. Hide the other panels.
public partial class FormTabsAlternative
: Form
{
int m_current = 0;
List<Panel> m_tabs = new List<Panel>();
public FormTabsAlternative()
{
InitializeComponent();
AddTab(pnl1);
AddTab(pnl2);
AddTab(pnl3);
AddTab(pnl4);
SetUpTabsAndButtons();
}
private void AddTab(Panel pnl)
{
m_tabs.Add(pnl);
pnl.Dock = DockStyle.Fill;
}
private void OnLeftClick(object sender, EventArgs e)
{
if (m_current > 0)
{
m_current--;
SetUpTabsAndButtons();
}
}
private void OnRightClick(object sender, EventArgs e)
{
if (m_current < m_tabs.Count - 1)
{
m_current++;
SetUpTabsAndButtons();
}
}
private void SetUpTabsAndButtons()
{
for (int index = 0; index < m_tabs.Count; index++)
{
var panel = m_tabs[index];
panel.Visible = index == m_current;
}
btnLeft .Enabled = m_current > 0;
btnRight.Enabled = m_current < m_tabs.Count - 1;
}
}
I have a custom Windows Forms Control to which I want to add a context menu. The custom control has an active selection that can be manipulated by keyboard or mouse. I set the custom control's ContextMenu property to the context menu I wish to show. When the user right-clicks, the context menu appears right where it is expected.
However, when the user presses the Menu key (or equivalently, Shift-F10) the context menu appears in the dead center of my control. I would like to be able to control the location of where the context menu appears depending on where the selection is in the control. How is this done? And does it also work for ContextMenuStrip?
EDIT
I'm writing up the worked solution given the answer below. First, set the ContextMenu property (or ContextMenusStrip property, as appropriate). Then, override the OnKeyDown method to intercept Shift-F10, and do an explicit Show() in that case.
this.ContextMenu = <my context menu>;
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyData == (Keys.Shift|Keys.F10))
{
ContextMenu.Show(this, new Point(<x and y coordinates as appropriate>));
e.Handled = true;
}
else
{
base.OnKeyDown(e);
}
}
This way, you don't have to muck with the logic that shows the context menu on right-click.
The Show() method of the ContextMenuStrip allows you to provide a control on which it is shows as well as the location.
For instance in example below:
this.contextMenuStrip1.Show(button1, new Point(50, 50));
It will display the menu 50 pixels to the right and below the button1. And when specifying only the location:
this.contextMenuStrip1.Show(new Point(50, 50));
The menu is displayed in the position relative to the main form.
I am new in C# and DevExpress. I'm trying to show another form by clicking a tile in the tileControl group but it doesn't show up. I just right-clicked at the tileControl, clicked view code and manually declared this since this doesn't automatically shows up if you double click a tile.
private void addTile_Click(object sender, EventArgs e)
{
var xForm2 = new XtraForm2();
xForm2.Show();
}
I just right-clicked at the tileControl, clicked view code and manually declared this since this doesn't automatically shows up if you double click a tile.
If I understand this correctly, you did not build your project using the C# code listed above, but only edited the source.
That does not work because what you edit in this way is not being loaded into the app.
Of course, I could be misunderstanding what you wrote.
I have a TabControl with AutoScroll set to true on tabpages. The tabpage contains a RichTextBox, which is bigger in height that the page, so vertical scrollbar appears on a TabPage. If I scroll the page down and then click on the RichTextBox, the page scrolls back to top. Any ideas on how to prevent such behaviour?
UPD: Here is a sample project which can reproduce the issue. The issue occurs when the RichTextBox receives focus. E.g. scroll tabPage1 down, then select tabPage2, return to tabPage1 and click on the RichTextBox.
Well, after a bit of struggling I've finally found a solution here. All I had to do was to create my own class inherited from TabPage and override the ScrollToControl method, making it return DisplayRectangle.Location.
This happens due to the fact that once you select the richTextBox and it is "out of sight" it goes to the current position(which in your case is not visible or at the top). If you select the richTextBox first and then scroll you will avoid this. One way you can do this is to Select() the richTextBox on application start.
Add this:
private void Form1_Load(object sender, EventArgs e)
{
richTextBox1.Select();
}
EDIT:
You can also add the Select() on TabIndexChanged as the behavior will reoccur if you change Tabs.
The answer while correct was difficult for me to initially understand without seeing the code.
Perhaps this helps others.
public class CustomTabPage : System.Windows.Forms.TabPage
{
protected override System.Drawing.Point ScrollToControl(System.Windows.Forms.Control activeControl)
{
//return base.ScrollToControl(activeControl);
return activeControl.DisplayRectangle.Location;
}
}
After defining your custom tabpage class, inherit now from this class in your form with your TabControl.
private CustomTabPage tpJobSetup;
In my application I have a DataGridView that is meant for configuring some options. The idea is that you can enter whatever text you want in the first column, but if you right click it will give you explicitly supported values. I need this to be a textbox rather than a dropdown list because I need to support editing invalid (or old) configurations.
What I want is the user to right click in the field name column and have a context menu that is valid based on what type of configuration this is. Therefore, I coded the following event
private void grvFieldData_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
// If this is a right click on the Field name column, create a context menu
// with recognized options for that field
if (e.Button == MouseButtons.Right && grvFieldData.Columns[e.ColumnIndex].Name == "clmFieldName")
{
ContextMenu menu = new ContextMenu();
if (_supportedDataGrids.ContainsKey((cmbDataGrid.SelectedItem as DataGridFieldList).GridName))
{
// Loop through all the fields and add them to the context menu
List<string> fields = _supportedDataGrids[((cmbDataGrid.SelectedItem as DataGridFieldList).GridName)];
fields.Sort();
foreach (string field in fields)
menu.MenuItems.Add(new MenuItem(field));
// Make sure there is at least one field before displaying the context menu
if (menu.MenuItems.Count > 0)
menu.Show(this, e.Location, LeftRightAlignment.Right);
}
}
}
This works "correctly", but the context menu is appearing at the top of the form, not where the mouse pointer is. If I change the Show() call to use the DataGridView instead of the form, I have the same issue but instead it appears at the top-left hand corner of the grid, not where the mouse is.
Oddly enough, if I change this event to a MouseClick event (instead of a CellMouseclick event) everything works and the context menu appears exactly where the mouse pointer is. The problem with this option is that the user might not be right clicking on the cell that is currently selected, which means that when they click on a menu item, the selected cell will be changed and not the cell they right clicked on.
Does anyone have any hints why context menus created with the CellMouseClick are not showing at the correct spot?
menu.Show(this, e.Location, LeftRightAlignment.Right);
The 2nd argument is the mouse location, relative to the cell's upper left corner. As programmed, you make that offset relative from this, the form, which will make the menu appear in the upper left corner of the form. Use the DGV as the 1st argument doesn't work either, now it is in the upper left corner of the grid.
A couple of ways to fix this, but this is the easy way:
Point pos = this.PointToClient(Cursor.Position);
menu.Show(this, pos, LeftRightAlignment.Right);
You can arbitrarily replace this with grvFieldData.
In the datagridview mouse click event:
if e.button= mousebutton.right
{
contextmenu1.Show(MousePosition);
}
try to use PointToClient to get proper spot
It's not showing in the correct spot because e.Location is the location relative to the parent object's top-left corner, which in this case is the cell itself. Location properties are always relative to their container.
To get the position of the mouse cursor relative to the top-left of the form itself, you can use
this.PointToClient(Cursor.Position);
I have solved this problem... ones could find this method strange, but it works fine !)
If we want to see a context menu while pressing right mouse btn in the datagridview cell, and right there, not in the middle of the screen or somewhere else, we need to:
make some variables
int x=0;
int y=0;
make an 'MouseMove' Event for datagridview1 lke that:
private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
x = e.X;
y = e.Y;
}
and
private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
contextMenuStrip1.Show(dataGridView1, x,y);
}
}
your welcome