Is there any way of adding custom variables to Controls in c#? - c#

I have multiple RichTextBoxes and I would like to store a boolean on them so I can access it for each of them. Is there any way?
I tried using the Extensions Methods, like I do to have more overloads for AppendText, but I had no luck there.

You can add whatever property you want. If you need to be able to change it at design time (from property editor) you just have to decorate with with the Browsable attribute.
Other attributes that might help:
CategoryAttribute - this attribute indicates in wich category of your property grid will reside your property.
DescriptionAttribute - this attribute adds a description for your property that will apear as a text description in the bottom of the property grid.
BUT if you cannot modify existing control, you must use inheritance (inherit in your case from RichTextBox). If the class is sealed then I would create another control that decorates current one (the decorator pattern) and add a new property on it.

You can use the Tag Property. Its defined on Control so is available for all controls including your RichTextBox MSDN

Quick simple solution (maybe not as elegant), but for the sake of simplicity, you can just create hidden fields using #Html.HiddenFor(x=>x.MyField1Bool). That is if you are posting back to the server. You'd need to create the extra boolean fields to your ViewModel of course.
Also, just in case you are planning to use javascript to access these booleans. You should have a look at data attributes, for example:
<input type="text" data-flag="true"/>
These are easy to access in javascript. And in Razor syntax you just add them as attributes.

Related

Adding controls dynamically with x:Name in MVVM

In our WPF application, we have a lot of forms with fixed fields. Every form should now be extended with fields the user can define himself. The database contains a table with these user defined fields, each with a label, a type (text, date, numeric, ...), etc.
I have found a lot of great solutions using DataTemplates, there is one issue with this however: it is not possible to generate a unique x:Name property for each field (using the field id for example).
Our application relies heavily on the x:Name property to do things as: show/hide fields, set a mask on numeric fields, move fields, ... All this functionality is read from the database, so a unique identifier per field is needed.
One solution would be to generate these fields with the x:Name in the codebehind (the Winforms way).
Another solution would be to change the functionality that uses the x:Name to using the Tag property.
Before I implement one of these solutions, I want to make sure there is no better way. Is there an MVVM way to dynamically generate fields with an x:Name?
Edit
There seems to be some confusion as to why I would need an x:Name for my fields in an MVVM scenario, so I'll clear it up with an example:
One requirement of our software is that every form field in our application can be set hidden or visible by the user. I'm talking about thousands of fields here. I could have created an property for every field that contains the visibility status and fill it from the database.
Instead, I have created an attached property (attached once in a style) that retrieves the visibility status based on the name of the field and apply it. So this functionality runs separately from the MVVM architecture (I never use the x:Name in the ViewModel). The disadvantage of using the attached property is that the form fields need an identification, being the x:Name property in my case.
Is there an MVVM way to dynamically generate fields with an x:Name
No, there isn't.
x:Name is a XAML directive that is used to uniquely identify a UI element in a XAML namescope and generate a backing field to store the value in the code-behind class of the view.
The view model doesn't and shouldn't know anything about this and it should certainly not generate such elements or backing fields as this would break everything that the MVVM pattern is all about.
If you do require to generate unique names for your UI elements for some reason, you should implement this functionality in the code-behind of the view.
MVVM is not about eliminating view-related code from the views, it is mainly about separation of concerns and testability.

Is there a generic way to save user layout?

I'm on a project where we use MVVM pattern.
By user layout: Sorting order of a grid, state of window or control.
For example is it possible to serialize all WPF control layout?
AvalonDock can serialize its layout, but that won't apply for grid column widths (AvalonDock is by all means great library!).
Also, I have written a set of classes that can make any property (of serializable type) of any object (in an WPF application) persistent only via adding a [Configurable] attribute to the property. It shouldn't be hard to customize it to save the properties based on a different criterion than presence of an attribute. But it saves the values on per-type basis, so it might be something else than you are looking for.
I can share if you wish.

Can I Re-Use Common Html in an ASP.NET Child Control?

I have 5 or so different pieces of HTML in my page that contain the same scaffolding HTML surrounding it, something like this:
//PanelBase.ascx
<div class="panel" id="[PANEL-SPECIFIC-ID]">
<h3>[PANEL-SPECIFIC-HEADER]</h3>
...
[PANEL-SPECIFIC-HTML]
...
</h3>
</div>
Where all the PANEL-SPECIFIC things are different for each panel type. Is there a way I can create a common base control to handle this scaffolding and inherit from it to supply the PANEL-SPECIFIC-HTML? The PANEL-SPECIFIC-ID and PANEL-SPECIFIC-HEADER I can just pass to the panel directly, but since the panel specific HTML is so large I don't want to pass it directly as a string.
Or is there some way to do it like this in each child control's ascx file:
<my:PanelBase PanelId="myChildPanel" Header="My Child's Header">
// HTML for my child panel.
</my:PanelBase>
Basically, I'm looking for some way to reuse the common portions of my control so I don't have to duplicate it for each child.
I guess the "most proper" way of doing this would be to have the main content of your container as a template, however that requires you to type <ContentTemplate></ContentTemplate> inside all your panels, which is less than ideal.
If I had to do this, I'd probably override AddParsedSubObject, collect any child controls into a collection and add them to a PlaceHolder or something similar in CreateChildControls. This can be done either with a custom control or a user control (.ascx).
For the headings and whatnot, just use Literals and create properties that wrap the Literal.Text properties.
Yes, and its generally good practice to do so. What would be ideal would be to put labels or literals in the places where you have content that would be modifiable. Then in the code behind you would put properties relating to each of them:
'These attributes allow you to specify individual properties about your control
'particularly if you want to be able to bind data to it, list it in the properties
'in your IDE, etc.
<BrowsableAttribute(True), Bindable(False), Category("Misc"), DefaultValue("true"), _
Description("Gets or sets the content title.")> _
Public Property DisplayContentTitle() As String
Get
Return _displayContentTitle
End Get
Set(ByVal value As Boolean)
_displayContentTitle = value
Me.litContentTitle.Text = value ' Optional
End Set
End Property
Then when you include the control in your page you would configure it in the following manner:
<asp:MyHtmlControl ID="blah" runat="server" DisplayContentTitle="Some text" />
This gives you the ability to modify, validate, manipulate or whatever in the code behind of the user control. It also allows the control itself to modified during runtime. You can also override loading and rendering events of your common control to perform specific actions based on any of these settings you create.
You might want to look into Nested Master Pages.

Modify default behaviour of PropertyGrid and TypeConverterAttribute

I am using a property grid to edit, amongst other things, a collection of items:
The default behavior for a collection provides a + button to edit each member of the array.
I am using a Form to edit this field, which is already wired up but I want to remove the ability for the user to edit the array by using the 'expander'
So it would look like this:
UPDATE1: made ProductIds an IList property instead of int[ ]
Now does this:
-----------------!
UPDATE2: made ProductIds a custom class, eg
MyWrappedCollection : IEnumerable<int>
so it now looks like this:
Sure, it still shows [+] but it doesnt expand to anything (ie disappears when you click it)
The attribute that controls whether a property is expandable or not is it's TypeConverter. The ExpandableObjectConverter is a built in class that provides the ability to expand a property and look at it's own. I am guessing by default that arrays and collections use this converter to display what is in them.
You can write your own TypeConverter which does not inherit from ExpandableObjectConverter and set it as an attribute on your property to remove the +.
By default for a collection, it uses [...] method. May be you could use a collection (For example a List) instead of an array.
By the way, any specific reason you use arrays?
You need to implement and apply a UITypeEdtitor. See How to: Implement a UI Type Editor
Override GetEditStyle of your UITypeEditor to return Modal

What is the use of Tag property in Tree view control C#?

What is the use of Tag property in Tree view control C#?
How can we work with it?
A common use for the Tag property is to store data that is closely associated with the control (from MSDN). Any type derived from the Object class can be assigned to this property.
It's a cheap way of avoiding inheritance to add just one Property.
Every control that inherits from Control in winform has a Tag property where you can store metadata for later use, for example you can store database id in that property for every item and load data from database on tree node click
As ArsenMkrt said, every control that inherits from Windows.Forms.Control has the Tag property. This is of type System.Object, so you can store anything you want.
The idea of the Tag property probably comes from VB6, which also has this, but in VB6 it is limited to String values.
When writing a UI, sooner or later you will find yourself handing an event in which you know the UI control that the event came from, but you also need to know what backing data that control is associated with. Usually, that problem can be solved with data binding, but not always. In the latter case, you can manually populate the Tag property with whatever you need to make the code work.

Categories