Hide my user control in designer form - c#

How i can hide my user control from designer form, to show in bottom of designer, like timers or openFileDialog...
What i want to do is a custom menuStrip, with animation, progressBar, dateTimePicker, and so on. But i don't want to be visible in designer, just like normal menuStrip.
I tried to make my user control as component, but if i do it, i lose others.
An example would be :
public class ExampleForm : Form
{
public ExampleForm()
{
CustomMenuStrip a = new CustomMenuStrip();
a.Items.Add(new CustomMenuStripItem()
{
///Stuff
});
}
}
public class CustomMenuStrip : UserControl
{
public List<CustmMenuStripItem> Items;
public CustomMenuStrip()
{
//Do Stuff
}
}
public class CustomMenuStripItem : UserControl
{
public CustomMenuStripItem()
{
//Do Stuff
}
}
Any ideas?
Thank's in advance.
Andrei

Related

Call Refresh event of grid Polymorphically C#

I have a main window in WPF and it contains:
A Tab Control having different tabs. Each tab has a different control in it and contains a data grid.
A frame control - it also has different controls respectively for data entry.
A Refresh Button (Yet to implement)
I have implemented the tab controls and frame for data entry successfully but problem is I cannot refresh the tab control until I switch across the tabs. I want to have a central Refresh button on main-window (one I aforementioned).
Can anyone guide me how can I do it?
And since tab's current object type will only be decided at the Run-time, so is it Polymorphism?
You can use an interface for all the usercontrols:
public interface IRefreshAble
{
void Refresh();
}
public interface ICanDeleteItem
{
void Delete(/*parameters omitted*/);
bool CanDelete { get; }
}
public interface IHoldATypedItem ///sorry for bad name
{
Type TheType { get; }
}
Then you implement this interface by the usercontrols:
public class TheUserControl : UserControl, IRefreshAble, ICanDeleteItem, IHoldATypedItem
{
public void Refresh()
{
//Your refreshcode
}
public bool CanDelete {get { /*code that indicates if an item can be deleted*/ } }
public void Delete(/*parameters ommited*/)
{
if(CanDelete)
{
//Delete Item
}
}
public Type TheType { get { return typeOf(Employee); } }
// otherstuff
}
Now you can put all of your UserControls(for example) in a List<IRefreshAble> and do stuff like:
foreach(IRefreshAble item in theList)
{
item.Refresh();
}
If you have more than this Refresh() method common for all Usercontrols you can just expand the interface for this members and get the polymorphism you need.

Visual Inheritance, Design-time support for extended custom controls

I'm extending my own custom control, which extends the UserControl class.
I can see all the elements fine in the extending class' designer, but all the properties of the extended custom control appear disabled and when selecting its element with the mouse a "locked" icon appears.
How can I fix that? I would like to be able to modify these properties from the designer.
EDIT: Definition of the custom control, which extends from UserControl.
namespace Wizard
{
[Designer(typeof(Wizard.StepDesigner))]
[DefaultProperty("TitlePanel, NavigationPanel")]
public partial class Step : UserControl
{
public Step()
{
InitializeComponent();
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Title TitlePanel
{
get
{
return this.title1;
}
set
{
this.title1 = value;
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Panel ContentPanel
{
get
{
return this.contentPanel;
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Navigation NavigationPanel
{
get
{
return this.navigation1;
}
}
}
internal class StepDesigner : ParentControlDesigner
{
public override void Initialize(System.ComponentModel.IComponent component)
{
base.Initialize(component);
if (this.Control is Step)
{
Step control = (Step)this.Control;
this.EnableDesignMode(control.TitlePanel, "TitlePanel");
this.EnableDesignMode(control.ContentPanel, "ContentPanel");
this.EnableDesignMode(control.NavigationPanel, "NavigationPanel");
}
}
}
}
As I already pointed out in the comments, the modifiers of the properties were all set to private and changing them to protected and rebuilding the solution fixed the "problem".

WPF - Class inheriting from a variable class

I have an application that can display items in two different ways, in rows using a StackPanel or icons using a WrapPanel. Which way it displays these items depends on a config setting. To populate these panels I have two seperate classes one inherits from the WrapPanel the other from the StackPanel. I was able to cut down on duplicated code using an Inferface. However I still had a lot of duplicated code the only difference between the code is the references to StackPanel or WrapPanel.
What I would really like to do is create a class that inherits from either the StackPanel or WrapPanel depending on the config setting.
public class ContainerBase : <wrap or stack>
{
//Do stuff!
}
Is this possible? Am I approaching this incorrectly?
When I said "composition but not inheritance" in first comment, I meant smth like the following:
public class PanelPresentatinLogic
{
public Panel Panel{get;set;}
public void DoSomeDuplicatingStuff()
{
//Do stuff! with Panel
}
}
public class SortOfStackPanel : StackPanel
{
private readonly PanelPresentatinLogic _panelPresentatinLogic;
public SortOfStackPanel(PanelPresentatinLogic presentationLogic)
{
_panelPresentatinLogic = presentationLogic;
_panelPresentatinLogic.Panel = this;
}
public void DoSomeDuplicatingStuff()
{
_panelPresentatinLogic.DoSomeDuplicatingStuff();
}
}
public class SortOfWrapPanel : WrapPanel
{
private readonly PanelPresentatinLogic _panelPresentatinLogic;
public SortOfWrapPanel(PanelPresentatinLogic presentationLogic)
{
_panelPresentatinLogic = presentationLogic;
_panelPresentatinLogic.Panel = this;
}
public void DoSomeDuplicatingStuff()
{
_panelPresentatinLogic.DoSomeDuplicatingStuff();
}
}
public class UsageSample
{
public void PopulateCollectionOfItemsDependingOnConfigHopeYouveGotTheIdea()
{
string configValue = configuration["PanelKind"];
PanelPresentatinLogic panelPresentatinLogic = new PanelPresentatinLogic();
Panel panel = configValue == "Wrap"
? new SortOfWrapPanel(panelPresentatinLogic)
: new SortOfStackPanel(panelPresentatinLogic);
// TODO: add panel to GUI
}
}
You can use Generics for this;
public class ContainerBase<T> where T : Panel
You can then use the config setting to initialize the right type.
In WPF you are intended to not use controls to populate itself. Instead, use MVVM pattern.
You can achieve your goal with only one class providing the data (tipically an ObservableCollection) and loading that "view mode variable" into a property at MVVM.
Then you can use a an ItemsPanel with an DataTemplateSelector to select the view.
May be you can use Panel?
public class ContainerBase : <wrap or stack>
{
//Do stuff!
}

User Control as container at design time

I'm designing a simple expander control.
I've derived from UserControl, drawn inner controls, built, run; all ok.
Since an inner Control is a Panel, I'd like to use it as container at design time. Indeed I've used the attributes:
[Designer(typeof(ExpanderControlDesigner))]
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
Great I say. But it isn't...
The result is that I can use it as container at design time but:
The added controls go back the inner controls already embedded in the user control
Even if I push to top a control added at design time, at runtime it is back again on controls embedded to the user control
I cannot restrict the container area at design time into a Panel area
What am I missing? Here is the code for completeness... why this snippet of code is not working?
[Designer(typeof(ExpanderControlDesigner))]
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class ExpanderControl : UserControl
{
public ExpanderControl()
{
InitializeComponent();
....
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
internal class ExpanderControlDesigner : ControlDesigner
{
private ExpanderControl MyControl;
public override void Initialize(IComponent component)
{
base.Initialize(component);
MyControl = (ExpanderControl)component;
// Hook up events
ISelectionService s = (ISelectionService)GetService(typeof(ISelectionService));
IComponentChangeService c = (IComponentChangeService)GetService(typeof(IComponentChangeService));
s.SelectionChanged += new EventHandler(OnSelectionChanged);
c.ComponentRemoving += new ComponentEventHandler(OnComponentRemoving);
}
private void OnSelectionChanged(object sender, System.EventArgs e)
{
}
private void OnComponentRemoving(object sender, ComponentEventArgs e)
{
}
protected override void Dispose(bool disposing)
{
ISelectionService s = (ISelectionService)GetService(typeof(ISelectionService));
IComponentChangeService c = (IComponentChangeService)GetService(typeof(IComponentChangeService));
// Unhook events
s.SelectionChanged -= new EventHandler(OnSelectionChanged);
c.ComponentRemoving -= new ComponentEventHandler(OnComponentRemoving);
base.Dispose(disposing);
}
public override System.ComponentModel.Design.DesignerVerbCollection Verbs
{
get
{
DesignerVerbCollection v = new DesignerVerbCollection();
v.Add(new DesignerVerb("&asd", new EventHandler(null)));
return v;
}
}
}
I've found many resources (Interaction, designed, limited area), but nothing was usefull for being operative...
Actually there is a trick, since System.Windows.Forms classes can be designed (as usual) and have a correct behavior at runtime (TabControl, for example).
ParentControlDesigner doesn't know what you want do. It only knows you want your UserControl to be a container.
What you need to do is implement your own designer which enables design mode on the panel:
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace MyCtrlLib
{
// specify my custom designer
[Designer(typeof(MyCtrlLib.UserControlDesigner))]
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
// define a property called "DropZone"
[Category("Appearance")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Panel DropZone
{
get { return panel1; }
}
}
// my designer
public class UserControlDesigner : ParentControlDesigner
{
public override void Initialize(System.ComponentModel.IComponent component)
{
base.Initialize(component);
if (this.Control is UserControl1)
{
this.EnableDesignMode(
(UserControl1)this.Control).DropZone, "DropZone");
}
}
}
}
I learned this from Henry Minute on CodeProject. See the link for some improvements on the technique.
In addition to the answer above. It is mentioned in the comments, that the user is able to drag the WorkingArea. My fix for that is to include the WorkingArea panel in another panel, setting it to Dock.Fill. To disallow the user to change it back, I have created a class ContentPanel that overrides and hides the Dock property:
class ContentPanel : Panel
{
[Browsable(false)]
public override DockStyle Dock
{
get { return base.Dock; }
set { base.Dock = DockStyle.Fill; }
}
}
For me, this makes it sufficiently safe. We are only using the control internally, so we mainly want to prevent developers from accidently dragging things around. There are certainly ways to mess it up anyway.
To prevent the working area from being moved/resized in the designer you have to create a class for that working area that hides the Location, Height, Width, Size properties from the designer:
public class WorkingArea : Panel
{
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new Point Location
{
get
{
return base.Location;
}
set
{
base.Location = value;
}
}
...
}

How do I tell the designer that my custom winforms control has a fixed height?

I've made a custom control and overridden SetBoundsCore such that the height of the control is fixed. I'd like the designer to show the same sort of resize boxes as the NumericUpDown has - just one at each end - so that it's clear that the control has a fixed height. How do I tell the designer that my control has a fixed height?
You have to apply a Designer attribute to your UserControl:
[Designer(typeof(UCDesigner))]
public partial class UserControl1 : UserControl {
public UserControl1() {
InitializeComponent();
}
}
The UCDesigner class is defined as follow:
class UCDesigner : System.Windows.Forms.Design.ControlDesigner {
public override System.Windows.Forms.Design.SelectionRules SelectionRules {
get {
return (base.SelectionRules & ~(SelectionRules.BottomSizeable | SelectionRules.TopSizeable));
}
}
}
Note: You'll have to add a reference to the System.Design namespace.

Categories

Resources