Is it possible to add a TrackBar control to a ContextMenu? So when I right click, my ContextMenu will drop down and a TrackBar will appear as a menu item?
If your context menu is a ContexMenuStrip, you can create an item in this way:
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.MenuStrip |
ToolStripItemDesignerAvailability.ContextMenuStrip)]
public class TrackBarMenuItem : ToolStripControlHost
{
private TrackBar trackBar;
public TrackBarMenuItem():base(new TrackBar())
{
this.trackBar = this.Control as TrackBar;
}
// Add properties, events etc. you want to expose...
}
Thanks to the ToolStripItemDesignerAvailability attribute, you can even see the item in the Forms Designer, as shown in the image below:
P.S.
This solution comes from this MSDN example
Yes, you need to set the context menu to user draw and draw the menu items yourself. You will have to create a custom MenuItem the implementes a TrackBar
For what it's worth for anyone who stumbles across this having problems with:
Constructor on type 'System.Windows.Forms.ToolStripControlHost' not found.
The only way I got it to work was by putting the derived control in it's own file. When it is in the same file as another control it confuses the designer.
Related
I am implementing context-sensitive help for an existing WinForms app built in Visual Studio .NET. I have added a HelpProvider to the form and set the HelpNamespace property to a wonderful .chm that covers every control and menu item on the form. I have set the necessary HelpKeyword on all the controls that derive from Control and so far all is great: F1 works perfectly.
My problem is that I can't work out how to do it for menu items. These use the ToolStripMenuItem class, which does not derive from Control and so has no HelpKeyword property. How should I provide context-sensitive help for individual menu items? Mr. Google has not been very forthcoming.
Using F1 is not a common way of providing help for menu items. Menu items usually use ToolTip, or show some help text in StatusBar or usually their comprehensive helps comes with Help content of main page.
I prefer to use one of above mentioned solutions, but here for learning purpose, I'll show what you can do using HelpRequested event of the form.
To handle help for form and controls, you can rely on the HelpRequested event of the form and controls.
Here you can rely on Form event to solve the problem. Since you have a HelpProvider on form, you should know HelpProvider handles HelpRequested event of all controls internally and, for controls having ShowHelp set to true, it sets Handled to true and prevents bubbling the event up so you can not have your custom code for handling help event if ShowHelp is true. So you should set ShowHelp for controls to false and just use HelpProvider as a help key holder.
To solve the problem using the HelpRequested event of the form, you should follow these steps:
For ToolStripMenuItems, use the Tag property as the help key holder.
For other controls, if you use HelpProvider to assign HelpKey, don't forget to set ShowHelp to false.
Handle the HelpRequested event of the form.
In the body of event handler, check if there is an active menu item on your form, then use the Tag property of the active item to show help. If there is not any active menu, use the ActiveControl property of the form to show the help.
Example
Here is a step by step example of how you can show help for menu items using F1 key. To do so, follow these steps:
Create Form, Menu and Controls - Create a Form and put some controls and a MenuStrip having some menu and sub menus on the form.
Configuring HelpProvider - Put a HelpProvider control on form and for each control assign suitable key to HelpKeyword property of control. Also set ShowHelp for each control to false. We will handle help in code.
Configuring Help for Menu - For a ToolStripMenuItem use its Tag property to store the help keyword.
Creating a helper method to find descendants of the Menu - Add a class to your application having the following code. In the following code, I've introduced an extension method to get all sub ToolStripMenuItem of a MenuStrip:
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
public static class ToolStripMenuItemExtensions
{
public static List<ToolStripMenuItem> Descendants(this MenuStrip menu)
{
var items = menu.Items.OfType<ToolStripMenuItem>().ToList();
return items.SelectMany(x => Descendants(x)).Concat(items).ToList();
}
public static List<ToolStripMenuItem> Descendants(this ToolStripMenuItem item)
{
var items = item.DropDownItems.OfType<ToolStripMenuItem>().ToList();
return items.SelectMany(x => Descendants(x)).Concat(items).ToList();
}
}
Handling the Helprequested event to show help - Handle the HelpRequested event of the form and implement the algorithm which I described above using the following code:
private void Form1_HelpRequested(object sender, HelpEventArgs hlpevent)
{
string keyword = "";
var selectedMenuItem = this.menuStrip1.Descendants()
.Where(x => x.Selected).FirstOrDefault();
if (selectedMenuItem != null)
keyword = selectedMenuItem.Tag?.ToString();
else if (ActiveControl != null)
keyword = helpProvider1.GetHelpKeyword(ActiveControl);
if (!string.IsNullOrEmpty(keyword))
Help.ShowHelp(this, "Help.chm", HelpNavigator.Index, keyword);
}
Note
For testing the solution you don't need a chm file having index and so on. You can simply show the helpkeyword in Text property of form. It means the solution is working and after that you can create suitable chm file.
You can use one of the other overloads of ShowHelp method of Help class based on your requirement.
There are HelpKeyword and HelpString extended properties for controls, pay attention which one you are using and get the same one in the HelpRequested event.
Don't forget to set ShowHelp to false. If you forget this step, the event will be handled internally in Helpprovider.
Don't forget to assign a help keyword to Tag property of menu items. To make it more friendly for future, you can simply create an extender provider that adds a help keyword property to menu items.
I have ribbon tabs, and there are buttons, textboxes,comboboxes in each tab. My problem is, I want to be able to scroll down and up with my mouse wheel (for the combobox), but instead, my mouse wheel changes the tabs. It doesn't affect the combobox in it. Is there a way to fix this? It is really annoying.
Too long for a comment, so I will post it here.
Try creating your own class that inherits from that Ribbon control. I don't have a ComponentOne library, so for this example, I am just calling the control "Ribbon":
public class MyRibbon : Ribbon {
public bool DisableMouseWheel { get; set; }
protected override void OnMouseWheel(MouseEventArgs e) {
if (!this.DisableMouseWheel) {
base.OnMouseWheel(e);
}
}
}
Rebuild your solution. Click on the "Show All Files" button from the Solution Explorer and open your designer file for your form. There should be two lines in the file that reference your Ribbon type, replace the type with your new MyRibbon class.
Now subscribe to the ComboBox's Enter and Leave events where you change the DisableMouseWheel property.
Make a backup of your work before trying this.
When I add krypton items to my form, they appear over the top of the others, how can I make it so that I can put something behind the other items?
Assuming you're using the Winform designer, you can right click a control and select 'Bring to Front' or 'Send to Back' from the context menu to change the control's 'z-order.'
The order of control appearing inside their parrent container is controlled by Z-Index.
Right click control in the designer. Select "Bring ro front" from the context menu.
If you doing it programmtiacly. All control in winforms environment have two methods : BringToFront() and SendToBack(). You can call it to setup z-index of controls.
If you want to specify Z-Index explicitly you may use this workaround:
public static class ControlExtension
{
public static void SetControlZIndex(this Control ctrl, int z)
{
ctrl.Parent.Controls.SetChildIndex(ctrl, z);
}
}
Usage:
button1.SetControlZIndex(10);
By default ComboBox and Button elements are not among those offered to add into a StatusStrip by WinForms designer (while DropDownButton and SplitButton are). Is there a way to add them there? As far as I've heard any control can be embedded there, but how?
More easily, you can cut a ToolStripComboBox created via the menu in a ToolStrip and paste it in the StatusStrip.
No lines of code written... and it works ;-)
You can implement easily inheriting from ToolStripControlHost:
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.MenuStrip |
ToolStripItemDesignerAvailability.ContextMenuStrip |
ToolStripItemDesignerAvailability.StatusStrip)]
public class ComboStripItem : ToolStripControlHost
{
private ComboBox combo;
public ComboStripItem()
: base(new ComboBox())
{
this.combo = this.Control as ComboBox;
}
// Add properties, events etc. you want to expose...
}
After rebuilding your solution you will able to see the item even in the designer:
P.S.
this item will be usable also in ContextMenuStrip and in MenuStrip.
EDIT:
To set a custom icon use ToolboxBitmapAttribute.
However, I noticed that actually there's a built-in combobox toolstrip item called ToolStripComboBox.
It has just no designer visibility for the StatusStrip , but it can be easily added to a StatusStrip by code, or, if you prefer, you can extend it giving the complete visibility:
[ToolboxBitmapAttribute("image path or use another overload..."),
ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.MenuStrip |
ToolStripItemDesignerAvailability.ContextMenuStrip |
ToolStripItemDesignerAvailability.StatusStrip)]
public class ComboBoxItem : ToolStripComboBox
{
}
If you want to add a simple button to your StatusStrip, you can do so using the Designer.
First, add a DropDownButton. Then, in the DropDownButton properties window, set the ShowDropDownArrow property to False.
Repeat for each additional simple button that you want to show in your StatusStrip.
First off, I'm new to WPF and C# so maybe the issue I have is really easy to fix. But I'm kinda stuck at the moment.
Let me explain my problem.
I have a WPF Window and two usercontrols (Controls and ContentDisplayer).
The usercontrol Controls, wich contains some buttons, is added in the XAML of the Window.
Nothing special here.
Window.XAML
<nv:Controls/>
Now, what I want to do is when a user is pressing a button in Controls, ContentDisplayer needs to be added to the Scatterview I have in my Window.
I solved the problem by adding the buttons to the Window, and not using the usercontrol Controls. But this is not what I want.
Window.XAML.CS
private static void Button_ContactChanged(object sender, ContactEventArgs e)
{
object ob = Application.LoadComponent(new Uri(
"NVApril;component\\XAML\\ContentDisplayer.xaml",
System.UriKind.RelativeOrAbsolute));
//Set a unique name to the UserControl
string name = String.Format("userControl{0}",
SurfaceWindow1_Scatterview.Items.Count);
UserControl userControl = ob as UserControl;
userControl.Name = name;
//Add the new control to the Scatterview
SurfaceWindow1_Scatterview.Items.Add(userControl);
SurfaceWindow1_Scatterview.RegisterName(name, userControl);
}
So the real question is: How do I add a usercontrol to the Window by pressing a button in an other usercontrol?
Thanks,
Toner
At the top of the window xaml add
xmlns:d="clr-namespace:SomeNamespace.Usercontrols"
where you these exist already, you can choose the namespace of your control from the intellesence list.
Then where you want to place the control type:
<d:yourusercontrolhere params />
and your usercontrols can be added there.
Within Controls expose an event that is fired when you want to add a new control.
public event EventHandler AddControl;
private void RaiseAddControl()
{
if (AddControl!= null)
{
AddControl(this, EventArgs.Empty);
}
}
Now sink that event in your Window
yourControl.AddControl += ContactChanged
In your window, it sounds like you need to add the event to the instances of Controls.
<local:ContentDisplayer>
...
<nv:Controls AddControl="ContactChanged"/>
...
Then in your ContactChanged event handler you can instantiate a new Controls control and add it to whatever collection you're using like in your Button_ContactChanged event handler above.
Let me know if you need further clarification.
I have no idea what you are trying to do your example,
So you have a control defined thus:
public partial class somecontrolname : UserControl
With your corresponding Xaml file
All you need to do to add it in code to your window is firstly you need a LayoutRoot such as Grid control in the window then just
[mylayoutcontrol].Children.Add(new somecontrolname());
Maybe I got wrong idea what you are trying to do, your example code doesn't make much sense to me, looks like you are trying to load the xaml source file