Right click menu under winforms - winforms

I want to make a right click menu for my winforms app. It will have the same two things in it no matter where it pops up. A little hunting and pecking leads me to the conclusion that winforsm either doesn't support this in a trivial way or has hidden it under some name I havn't guessed yet. I think I can make it work with the Click event and manually creating a menu in the right place, bla bla bla... Yuck, I can thing of a half dozon thing right now that I would get wrong the first time around. Someone has got to have a better way.
Am I missing some easy way to add this?
Is there some library/widget I can copy/paste in to handle the grunt work for me?

Add a System.Windows.Forms.ContextMenuStrip item to the form, then set the form's ContextMenuStrip property.

Put a ContextMenuStrip on your form, design your menu, then set the ContextMenuStrip property on the form to the component created.

After putting a ContextMenuStrip on your form, Add it to your Control (you can do it in Control's Properties) and then , use code like this for showing menu:
private void myTree_MouseClick(object sender, MouseEventArgs e)
{
myTree.ContextMenu.Show(myTree, new Point(e.X, e.Y));
}
more on MSDN.

Related

How to do Drag and Drop in WPF between two lists?

I'm having a hard time solving an issue of mine, I'm literally going mad.
Here's the idea: I have two ListView elements, and I need to open a dialogue when an element drops from the first list onto the second, but I need both the information from the element being dropped and the element being added to fill in the dialogue.
The thing is, I can't even get the basic functionality right - and that is opening the dialogue on drop.
I'm going to learn the D&D technique from start to finish, but I quickly need a way to at least call the dialogue.
After writing and erasing some code the only thing I have left is the following:
private void lvListaRadnika_MouseDown(object sender, MouseButtonEventArgs e)
{
DragDrop.DoDragDrop(lvListaRadnika, presenter.Selected, DragDropEffects.None);
}
private void ListView_Drop(object sender, DragEventArgs e)
{
DodavanjeRezervacije dr = new DodavanjeRezervacije(new DodavanjeRezervacijePresenter(null,true));
dr.Show();
}
At this point I need something to happen and after that I'll see about adding all the necessary checks, feeding the dialogue with the data as well as adding an adorner.
If someone could explain as much as possible about drag and drop along the way I would highly appreciate it, but at this point I only really need this to fire up.
Converting my comment into an answer:
You should really give a try to the Gong WPF Drag And Drop Framework. I helps do these kind of things in a really clean and nice (MVVM) way.
I had answered a similar question where i have a sample project demo to drag drop between any two controls.
Just refer to the answer here and you can use that control.

give focus to textbox when control is shown

There is a custom UserControl which contains a TextBox. How do I give focus to the textbox when UserControl is shown? I've tried calling TextBox.Focus on UserControl.IsVisibleChanged and TextBox.IsVisibleChanged event, but that didn't help. What else can I try?
It seems that something causes TextBox to loose focus. The approach that I've mentioned normally works. How can I find out what causes the TextBox to loose focus? I've tried listening to TextBox.LostFocus event, but it's parameters don't contain much valuable information and I also don't see previous methods in the stack trace.
The code:
void TextBox1_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (this.TextBox1.IsVisible)
this.TextBox1.Focus();
}
As I've said before, it works if I use same code on a similar scenario in a test project, but it doesn't work in my application (the application is big and I am basically fixing bugs in it, and this one is amongst them). So I think that the problem isn't that focus is set improperly (as I've thought when I was opening this question), I think that the problem is that something else resets the focus. I am trying to find what it is here: Find out why textbox has lost focus .
I'm not exactly sure why it doesnt come back on visibility changed... however when I did TextBox1.Focus() in IsEnabledChanged it worked like a charm.
Use the UC as the bridge, when you let the UC shown, then call some function to focus the TextBox.

How to fix selected Item in a collection control on a user control (using the MVVM implementation) in WPF

I hope someone can help me...
Josh Smith did a great article on "WPF apps with the Model-View View-Model", and included in his article was the following code sample.
If you download the code sample and run the app and view all customers, then select a company (e.g. 4th company), then click "Create new customer" (which will open a tab of the new customer), and then click back on the "All Customers" tab, and then using the keyboard try and move the selected item up one to the item directly over the current selected item, it doesn't! Instead the selector starts at the top again.
I am not sure why this happens, but I want it so that when you click up, it goes one item up, rather than starting at the top of the list. I suspect this has to do with FocusManager, but am not sure.
Does anyone know why the control behaves in this manner? Is it possible, and what approach I should take to modify this code and get it to not "reset" the selected item?
I have implemented a project based off this template and for functionality reasons I need to get the keyboard to move the selector up & down without it resetting.
in the example you've provided setting IsSelected property does not affect the logical focus so the focus is set by default. Workaround I have in mind currently is to force focus for the element in codebehind. As an example add handler to selectionchanged of the listview like this:
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count == 0 || e.RemovedItems.Count > 0) return;
var item = (CustomerViewModel) e.AddedItems[0];
var container = (UIElement) listView1.ItemContainerGenerator.ContainerFromItem(item);
container.Focus();
}

Designing Windows.Form with multiple panels -> How to hide one panel (like a PS layer)

How can I hide one panel in Visual Studio 2008 Form Designer like a layer in PS? Otherwise, can someone recommend another better method to design multiple "screens" that must be clicked through by the user?
What you describe is a wizard, and you might want to investigate the approach from Eric J.
However, when I have cases where I want to have multiple panels in the same space within my UI and I want to switch between them in the designer, I like to use a TabControl and hide the tabs on the TabControl. This makes the UI easier to manage at design time and the code is pretty simple to switch between the tabs at run time.
I made a custom control that derives from TabControl called HiddenTabsControl that is very simple. The class only overrides the WndProc and lets the TabControl base class handle everything else. All you need to do is:
Add a New Item to your project
Choose Custom Control,
Name it something like HiddenTabsControl.
Change the base Class to TabControl, remove the Constructor and the OnPaint override that Visual Studio added.
Copy this override for WndProc into the class:
protected override void WndProc(ref Message m)
{
// Hide tabs by trapping the TCM_ADJUSTRECT message
if (m.Msg == 0x1328 && !DesignMode)
{
m.Result = (IntPtr)1;
}
else
{
base.WndProc(ref m);
}
}
Now you can change tabs in the designer and design the UI easily and in the code you can handle events to change tabs as needed. Changing the Selected tab is easily done with:
this.hiddenTabsControl.SelectedTab = this.tabPageYouWantVisible;
One side effect of removing the tabs is the space that the tabs occupy when the control is constructed. Removing them will make the space the HiddenTabsControl occupies change by shrinking it. I usually set the Anchor of the HiddenTabsControl to bottom to keep it from shrinking.
I used this Wizard code in a recent project and it worked well.
It provides the basic experience you are after.
Another less elegant, but quick hack, approach is to simply not add the panel to the parent form until runtime. In doing that, the designer has no idea where the panel belongs prior to compilation, and it won't be displayed.
For example, find the block of code where you add controls to the parent form:
//this->Controls->Add(this->panel_X);
this->Controls->Add(this->tabControl);
this->Controls->Add(this->menuStrip_topMenu);
Comment or remove the statement, then find the handle to the event that occurs when the form is loaded:
this->Load += gcnew System::EventHandler(this, &MainForm::MainForm_Load);
Then in the definition of the event handler, add the control to the form:
System::Void MainForm_Load(System::Object^ sender, System::EventArgs^ e) {
...
...
this->Controls->Add(this->panel_X);
}
I haven't experienced any unwanted side effects by doing this, but if anyone has a good reason to not I'd be interested in hearing it.

What causes a window to not appear in the taskbar until it's Alt-Tabbed to in Vista?

When our app is started programatically (either through custom action in MSI installer or when starting a new instance) in Windows Vista (also happens in Windows 7 Beta) it won't appear in the taskbar and isn't focused. Alt-tabbing to it will make it appear in the taskbar properly and stay there.
What causes this? I've seen this in some other apps before as well, but not sure why. Out app is .NET WinForms app. Never see this happen in XP, only Vista and 7
Edit: Well, it seems like the only time this happens reproducibly is when it's run by the installer, I believe there's other times it occurs, but I might just be crazy. The launching code is a bit complex to post because we handle various command line launch parameters and it launches a signin form before actually launching the main app etc.
Has anyone had to deal with this scenario before and worked it out?
Try checking your main application form "Form Border" property.
If it's ToolWindow (Fixed or Sizable), try changing it to FixedDialog for example.
This solved the problem in my case.
The usual reason for this is that your main application window doesn't have the window styles that let Windows know it's a main application window (rather than a tool window or a dialog box). So Windows is having to guess based on how the app was started, etc.
Use Spy++ to complare the window styles (especially extended styles) if your window to that of some other window that doesn't have this problem. Are you missing the WS_EX_APPWINDOW style? Are any other styles/extended styles different from other top level windows?
G.So's answer made me find the solution for my problem, wich was caused by the fact that i had my form sizable from launch, but set to borderless in the load void.
If anyone is interested in how i managed to keep the switch to borderless and have it pop up as it should in the taskbar without any dirty hacks.. here it is..
Make a new event from the form on the form's "Shown" event, and put your line of code for switching to borderless in here. Problem solved :)
private void Form1_Shown(object sender, EventArgs e)
{
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
}
and for the lazy ones ;) >>>>
this.Shown += new EventHandler(Form1_Shown);
Thanks again G.So for clearing up what could cause this in the first place.
I stuggled with this issue as well, and found like a previous commenter said, you cannot have anything in the form's Load() event that changes that FormBorderStyle property. Move anything that changes it to the Shown() event.
Well, one solution is to use a hack like this. That's really not what it's for.
Usually the decision of whether a window will be in the taskbar or not is based on the border styles it uses. The article I linked to provides a bit more detail. The article's comment about the window having an owner or not is quite possible highly relevant to your issue, since the window might somehow be getting a different owner when launched by the installer.
That article is in VB but it's all based around API calls so the info it provides is pretty language independent.
Never see this happen in XP, only Vista and 7
Maybe it's a bug in Vista...?
What happens if you call SetForegroundWindow() (or equivalent in .Net)?
Edit
I did of course mean "BringWindowToTop()".
Or do both.
We had this same problem and fixed it by setting the form property showintaskbar property to true.
Weird that all windows os's dont run apps in the same way!
In our situation, this was tracked down to the form's text property being changed within the Load event.
After putting this inside a BeginInvoke, this odd behaviour no longer happened.
Hope this helps anyone else.
Example
private void Form_Load(object sender, EventArgs e)
{
...
...
...
// this needs to be inside a BeginInvoke otherwise it messes with the taskbar visibility
this.BeginInvoke(new Action(() =>
{
this.Text = "Something new";
}));
...
...
...
}
We encountered the same issue, also in Windows 8. Sometimes the form was receiving correctly the focus, but say just ~30% of the time.
We tried different solutions, but actually the one that worked was the following:
private void OnFormShown(object sender, EventArgs e)
{
// Tell Windows that the Form is a main application window
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
// Even if true, enforce the fact that we will the application on the taskbar
this.ShowInTaskbar = true;
// Put the window to the front and than back
this.BringToFront();
this.TopMost = true;
this.TopMost = false;
// 'Steal' the focus.
this.Activate();
}
Moreover, we ensure also not to set the title of the form during the Load event.

Resources