In my asp.net 4.0 application I have a standard set of tabs controls across the application that has one tab for Search, one for View and one for Reporting. I am in the process of updating those tabs and I was hoping to be able to wrap their functionality up into a single user control since they all function in pretty much similar ways. The issue I am having is how to create a property called SeacrhTab/ViewTab/ReportTab that allows me to assign a different user control to it depending on the area of the application (e.g. CompanySearchControl, ContactSearchControl, etc.) Anyone ever tried to accomplish something similar? How should I approach this?
You should just be able to create a regular property in the partial class definition in your code behind page. Make it public and of the type of generic class that includes all tab controls and you should be set.
I have not made other controls properties of a user control but I have certainly used all sort of other custom classes as properties of user controls, so I don't see why it wouldn't work.
Assuming CompanySearchControl and ContactSearchControl both inherit from GenericSearchTabControlClass, for instance:
public GenericSearchTabControlClass SearchTab {get;set;}
public GenericViewTabControlClass ViewTab {get;set;}
public GenericReportTabControlClass ReportTab {get;set;}
Create an enum for the specific layout, view or tab definition ie: SearchTab, ViewTab etc. specify that as a Property of your UserControl, then use that propery to create, or hide and show a specific PlaceHolder or Panel depending on the required layout, or functionality.
public enum ControlLayoutEnum
{
SearchTab = 0,
ViewTab = 1,
ReportTab = 2
}
public class TabViewControl: System.Web.UI.UserControl
{
public ControlLayoutEnum ControlLayout { get; set; }
protected override OnInit(object sender)
{
// Create controls required or Hide/Show PlaceHolder or Panel etc
switch (this.ControlLayout)
{
case ControlLayoutEnum.SearchTab: // Create Search Layout
break;
}
}
Related
I am building some applications that use OPC to control some industrial automation. I have decided it might be a good idea to create some custom controls for standard things I will use such as buttons and text boxes. One of my main reasons was that I felt in an ideal pattern the end object i.e. the button is the one who holds information about the OPC item it refers to otherwise in a typical application my Form class gets polluted by tons of variables that are in my mind scoped more global then they should. I started then by using the Tag property of the button but this requires some overhead code that is the same for each instance. I felt like the right thing to do is subclass controls that I would like to use and provide properties to configure each one.
With that context in mind my real question is this. To make it as portable as possible I decided there should a property to define the OPC Group. I declared a property like this
public class OPCButton : Button
{
[Category("OPC")]
public OPCConnectedGroup
{
get { return _OPCGroup; }
set { _OPCGroup = value; }
}
}
This shows up int the property list when I add the control but I am unable to bind this property even though my Form1 contains
public OPCConnectedGroup Connection1 = new OPCConnectedGroup();
I have resolved that the way to solve this is to probably create an additional control like OPCGrp that can be added to a Form then the Controls can reference this. To test I added a property of type Button and sure enough when I added it and browsed to the property it gave me options for all the buttons on the Form. I have no huge problems with this approach I just want to make sure that Im following a prototypical pattern because I will be responsible for maintaining the control library but not always implementing and Im trying to get it down to a 1-2 step process to implement a control.
Thanks
Matt
When defining OPCConnectedGroup you can inherit Component class.
This way if you have a property of type OPCConnectedGroup in your OPCButton, then at design time, you can put instances of OPCConnectedGroup on the form, and then if you choose your OPCButton at designer, that property of type OPCConnectedGroup will show as a drop down list that you can select one of instances that you put on the form for it.
Example:
If I have such MyButton and MyClass:
public class MyButton : Button
{
public MyClass MyClassInstance { get; set; }
}
public class MyClass : Component
{
public string SomeProperty {get;set;}
}
Then you can put some (or one) instance of MyClass on the component tray of the form:
And then if you select MyButton on your form, you can choose one of MyClass instances from in property grid:
I'm making such a tabbed "Product Version Control", using an UserControl which encloses fields, checkboxes, text areas, grids, and so on. At runtime, when I add a new tab (like we have on browsers), I instantiate a new UserControl (with all components inside). The issue is: I can get all internal component values and fill an object to persist, but not the other way. I can take all values from Object and set them to EditValue (or Text/Value properties) properties of internal components, but they are not showing up to the user.
Consider:
All my internal components have public set/get methods like shown below
public class TabVersion : UserControl
{
...
public DevExpress.XtraEditors.SpinEdit seRevision
{
get
{
return _seRevision;
}
set
{
_seRevision = value;
}
}
...
}
Inside TabVersion class, I have a "fill" method which receives an "Version" object and set all internal components "EditValue" properties like shown below:
public class TabVersion : UserControl
{
...
public void FillTab(Sheet sheet)
{
...
this.seRevision.EditValue = sheet.NumRevision;
...
}
...
}
At runtime, all EditValue component properties are filled but not showing to the user. Do I have to set "Enabled" or "Visible" properties for each component inside my usercontrol?
Any Ideas?
Thank you in advance.
Well... After googling everywhere with no goal, I wrote a "Fill" method that fills all DevExpress controls inside my user control, and called it inside the "Shown" event at the parent form. I think that's a bug from DevExpress, because all Windows default components works all right when I give them their respective values. That's it.
I have a custom control that I have created with a bunch standard windows asp controls on it.
Question:
Is it possible to inherit the properties of the parent control into the custom control without re-inventing the wheel?
So for example I have a control with a Button, a TextBox, and a Label.
Normally I can access the properties of that control via Lable1.Text however when these controls are places within a custom control how do I access them without encapsulating all the properties of that control individually.
I was hoping for something like CustomControl1.Lable1.Text or is this not possible
If I use this
public Label lbMovieName
{
get { return this.lbMoveName; }
set { lbMovieName = value; }
}
I get what I need but can you please tell me why I should not do it?
The easiest way is to expose the control through a public read-only property:
public Label MyLabel
{
get { return this.Label1; }
}
However encapsulating just the values you want to expose is definitely a cleaner solution for several reasons:
you can abstract away that actual control type versus being tied to a Label in this case - if you expose the control it will be difficult to swap out the Label with MyNewCoolLabel, for example
You may be exposing more that you want to - the client could change the display properties of the label, etc.
If you are trying to avoid creating properties you can make the controls public (this is not sound OO development). As others have already mentioned you'd be much better served exposing the information that you'd want to share via properties.
The best way and the best practice, I think, is to create properties of your custom control that expose only and exactly what you need. Everything else inside your control should remain private. Something like this:
public string LabelText {
get { return this.Label1.Text; }
set { this.Label1.Text = value; }
}
... and so on for the rest of the properties you need exposed. This will give you nice intellsense response in the designer as well.
I created this User Control:
I added that User Control to the main Form and now I want to customize it.
So I will have to add text to those 3 Buttons, text in Label, populate ListBox and setting Click Events for the buttons.
What is the proper way to do that?
I looked around on the web and apparently the way to do it is to add public properties in user control that would expose individual property of control that I need.
Something like:
public string Button1Text
{
get
{
return btn1.Text;
}
set
{
btn1.Text = value;
}
}
If I go this route, I would have to add quite a few public properties to this simple user control.
But isnt it easier just to expose whole control in user control like this?
public Button MyButton1
{
get { return this.btn1; }
set { this.btn1 = value; }
}
That way the Main Form can simply access control and its properties as they are needed.
First method is better from the perspective of encapsulation. Second method causes users (forms) of your control to depend on the view of your control, and this prevents changes to the view in the future.
The first bit of code is the correct way to do it. You will have to create a lot of them but it is the proper way to do it.
The first one is much better where you only create properties for each individual property of the button you wish to be able to access from the Parent control.
If you use the second way, then anyone who wishes to use your control will be able to move and resize individual controls inside your control. Then it really isn't a custom control anymore, but more of a panel that is harder to use than a panel. I can't think of any reason why to be able to allow the Parent to move around individual elements in a subcontrol.
I want to have the WPF controls inherited like this,
public class BaseView : UserControl
{
...
}
public class BaseListView : BaseView
{
...
}
public class TeachersListView: BaseListView
{
}
public class StudentsListView : BaseListView
{
}
Here "BaseListView" is the base classed. This classes may have several functionalities which depends on the ListView present in "BaseListView". I want to inherit this "BaseListView" to several views which may add several column's and with different databindings. So my requirement is
class BaseListView : BaseView
{
This class will have the UI parts like commandStrip and followed by "Empty ListView".
This "ListView" may not hold any columns in it.
}
class StudentsListView: BaseListView
{
In **XAML** part, Columns and its appropriate Data Binding will be added. I need to access the controls in .cs file. so that i can access the controls.
void FindAndHighlightColumn()
{
// get the columns to find and search the list view and highlight.
}
}
How can i achieve this, what is the right way to do this.
I think you want to create a UserControl (Items- or ContentControl) with some basic functionality like FindAndHighlightColumn().
You can create your BaseListView "lookless" and then use ControlTemplates to get several flavours of it (create styles like "StudentListViewStyle" etc., each with an appropriate ControlTemplate). A ControlTemplate is a view, so you can specify different bindings in each template, to access controls by their names you need to define a convention with certain parts named 'PART_XY' etc., look at the standard ProgressBar-Control for an example.
Are you using Model-View-ViewModel architecture? After reading your question, my initial thought is that I would not use inheritance to the extent you are thinking of. Instead, I would consider composition.
For example, could you create a composite StudentsListView by composing a .xaml file of multiple user controls? Maybe a user control to display your commandStrip and another user control to display the appropriate ListView (e.g. StudentListViewUserControl, TeacherListViewUserControl, etc.).