Add Custom Property in WebPart Editor Zone - asp.net

I have webparts which display the content.
Using Webpart Editor zone I need to select display style.
By Selecting the Style i need the data to be displayed either in Grid or List or Rolling (from Dropdownlist).
How can i add custom property in Webpart Editor Zone.
I'm newbie to this.
I have Google'd about this but got nothing.
Any help is Appreciated.

As Mathew Collins writes:
I didn't get any replies here, but I was able to figure out a way to
do some of these.
In the end I decided to overirde the EditorPart class.
The ApplyChanges() and SyncChanges() methods essentially just persist the changes from the page to the personalization blob and
vice-versa. It's a matter of rendering some controls on the page, and
mapping the values to the properties of the web part in these methods.
Like
Imports Microsoft.VisualBasic
Imports System
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Data
Imports FormsUtilities
Namespace CustomEditorZone
Public Class CustomEditor : Inherits EditorPart
Public Sub New()
Me.Title = "Change Display Style"
End Sub 'New
Private PartPropertyValue As DropDownList
Protected Overrides Sub CreateChildControls()
Controls.Clear()
PartPropertyValue = New DropDownList()
PartPropertyValue.AppendDataBoundItems = True
PartPropertyValue.Items.Add("")
PopulateControl(PartPropertyValue)
Me.Controls.Add(PartPropertyValue)
End Sub 'CreateChildControls
Public Overrides Function ApplyChanges() As Boolean
EnsureChildControls()
Dim MyWebPart As GenericWebPart = DirectCast(WebPartToEdit, GenericWebPart)
Dim MyControl As CustomWebPart.WebPartBaseConsumer = DirectCast(MyWebPart.ChildControl, CustomWebPart.WebPartBaseConsumer)
MyControl.DisplayStyle = PartPropertyValue.SelectedItem.Text
Return True
End Function 'ApplyChanges
Public Overrides Sub SyncChanges()
Try
EnsureChildControls()
Dim MyWebPart As GenericWebPart = DirectCast(WebPartToEdit, GenericWebPart)
Dim MyControl As CustomWebPart.WebPartBaseConsumer = DirectCast(MyWebPart.ChildControl, CustomWebPart.WebPartBaseConsumer)
Dim CurrentDisplay As String = MyControl.DisplayStyle
For Each Item As ListItem In PartPropertyValue.Items
If Item.Text = CurrentDisplay Then
Item.Selected = True
Exit For
End If
Next
Catch ex As Exception
End Try
End Sub 'SyncChanges
Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
Try
writer.Write("Display Style :")
writer.Write(" ")
Me.PartPropertyValue.RenderControl(writer)
Catch ex As Exception
End Try
End Sub 'RenderContents
Private Sub PopulateControl(ByRef PartPropertyValue As DropDownList)
PartPropertyValue.Items.Add("Grid")
PartPropertyValue.Items.Add("List")
PartPropertyValue.Items.Add("Rolling")
End Sub
End Class 'CustomEditor
End Namespace

Related

Custom LiteralControl does not insert into page

I am tired of creating a System.Web.UI.LiteralControl everytime I need to add a control to my in webforms. So, I decided that it would help me if I created a custom LiteralControl that initialized with that value.
So, I created this very simple class:
Public Class ScriptLiteralControl
Inherits System.Web.UI.LiteralControl
Private _Text As String
Public Sub New()
Me.InitControl()
End Sub
Private Sub InitControl()
Me._Text = "<script type=""text/none""></script>"
End Sub
Public Overrides Property Text As String
Get
Return Me._Text
End Get
Set(value As String)
Me._Text = value
End Set
End Property
End Class
But when I do this in my webpages:
dim slc as New ScriptLiteralControl
Me.Header.Controls.Add(slc)
Absolutely nothing gets added.
According to the ASP.NET documentation I've read, all I had to do was basically override the Text property in my implementation but that doesn't seem to be working.
Can someone tell me what obscure .net rule I am not following in my implementation?
You shouldn't have to override the Text property. I think that's what's causing your problem. Try this:
Public Class ScriptLiteralControl
Inherits System.Web.UI.LiteralControl
Public Sub New()
Me.Text = "Put your script text here"
End Sub
End Class

Typecasting asp.net webControl to generic type with onClick event

I'm trying to find a way in which I can create a collection of various webControl's and then add a "onClick" event handler to these various controls, i've tried creating a reimplementation of "webControl" with a registered "onClick" event but I get a typecast error. Could anyone suggest how I could achieve this.
exception:
Exception Details: System.InvalidCastException: Unable to cast object of type 'System.Web.UI.WebControls.RadioButtonList' to type 'Club.WebControlButton'.
new webControl class:
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> Public Class WebControlButton
Inherits WebControl
Implements IPostBackEventHandler
' Define the Click event.
Public Event Click As EventHandler
' Invoke delegates registered with the Click event.
Protected Overridable Sub OnClick(ByVal e As EventArgs)
RaiseEvent Click(Me, e)
End Sub
' Define the method of IPostBackEventHandler that raises change events.
Public Sub RaisePostBackEvent(ByVal eventArgument As String) _
Implements IPostBackEventHandler.RaisePostBackEvent
OnClick(New EventArgs())
End Sub
End Class
Private Sub AddOnClickStringsToElements()
Dim divider As Integer = If(onClickElements.Count > 0, onClickElements.Count, 1)
Dim percentIntervals As Integer = 100 / divider
For Each element As Tuple(Of String, WebControl, Integer) In onClickElements
If element.Item3 < 1 Then
element.Item2.Attributes("onClick") = GetAnimateJavascript(percentIntervals)
Else
element.Item2.Attributes("onClick") = GetAnimateJavascript(element.Item3)
End If
//throws typecast exception here
AddHandler CType(element.Item2, WebControlButton).Click, AddressOf UpdatePercent_OnClick
Next
End Sub
It looks like the onClickElements collection contains an actual RadioButtonList control, not a control which derives from your WebControlButton class.
Any control which you are putting into the onClickElements collection must derive from WebControlButton for that casting operation to work e.g.
Public Class MyRadioButtonList
Inherits WebControlButton
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
' Create your radio button list here..
End Sub
End Class
An easier way would be to make an interface, such as IClickable...something a bit like this..sorry I didn't type it in VS so not sure if I got the syntax exact.
Public Interface IClickable
Public Event OnClick()
End Interface
Public Class MyRadioButtonList
Inherits RadioButtonList
Implements IClickable
Public Event OnClick Implements IClickable.OnClick
Private Sub RaiseOnClickEvent Handles Me.OnSelectedIndexChanged
RaiseEvent OnClick()
End Sub
End Class
And then..
For Each element As Tuple(Of String, WebControl, Integer) In onClickElements
If TypeOf(element.item2) Is IClickable Then
AddHandler CType(element.Item2, IClickable).OnClick, AddressOf UpdatePercent_OnClick
Else
Throw New Exception("A control of type IClickable was expected")
End If
Next

Creating UpdatePanel dynamically for a custom control is causing a full post back

I've been jammed on this for a day now. I need to create a custom control, and for a proof of concept, I am trying to create the UpdatePanel and add a button into it. It always causes a full page post back.
Code (custom control):
Imports System.Text
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.ComponentModel
Imports AjaxControlToolkit
<Designer(GetType(HMXICDSearchToolDesigner))> _
Public Class HMXICDSearchTool
Inherits HMXISBaseCompositeControl
Implements INamingContainer
Private Const DEFAULT_WIDTH As Integer = 650
Private Const DEFAULT_HEIGHT As Integer = 450
Private _pnlUpdate As UpdatePanel = Nothing
Private _btnTest As Button = Nothing
Private _lbl As Label = Nothing
Protected Overrides Sub CreateChildControls()
MyBase.CreateChildControls()
_pnlUpdate = New UpdatePanel()
With _pnlUpdate
.ID = "pnlUpdate"
.ChildrenAsTriggers = False
.UpdateMode = UpdatePanelUpdateMode.Conditional
End With
_btnTest = New Button()
With _btnTest
.ID = "btnTest"
.Text = "Test Button"
.CausesValidation = False
AddHandler .Click, AddressOf Btn_Click
End With
_lbl = New Label()
With _lbl
.ID = "lbl"
.Text = "Hello!"
End With
_pnlUpdate.ContentTemplateContainer.Controls.Add(_btnTest)
_pnlUpdate.ContentTemplateContainer.Controls.Add(_lbl)
Dim aTrigger As AsyncPostBackTrigger = New AsyncPostBackTrigger()
With aTrigger
.ControlID = "btnTest"
.EventName = "Click"
End With
Me._pnlUpdate.Triggers.Add(aTrigger)
Me.Controls.Add(_pnlUpdate)
Me.Style.Add("background-color", "red")
Me.Height = 500
Me.Width = 500
End Sub
Protected Sub Btn_Click(ByVal Sender As Object, ByVal e As System.EventArgs)
If Not Me.Page.IsPostBack Then
Me._lbl.Text = "Async postback."
End If
End Sub
End Class
Any thoughts would be greatly appreciated. I have tried toggling ChildrenAsTriggers, putting this code in Me.Load, among other things.
It was performing a partial postback the whole time.
I made the mistake of testing to see if it was a partial postback like so:
If Page.IsPostBack Then
'something here
End
When I should have been checking this
Me.ScriptManager.IsInAsyncPostback
This: Page.IsPostBack will be true even if it is performing a partial postback.

Untyped to strongly typed datatable

I tried to make some experiment today. I have an application that uses untyped datatables as the model entities.
They are all made like:
Imports System.Data
Imports System.Runtime.Serialization
Imports System.ComponentModel
<DesignerCategory("Code"), system.Serializable()>
Partial Public Class SomeTable1
Inherits DataTable
#Region
Public Const TABLE_NAME As String = "SomeTable1"
Public Const FIELD_SomeField1 As String = "SomeField1"
Public Const FIELD_SomeField2 As String = "SomeField2"
#End Region
Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
MyBase.New(info, context)
End Sub
Public Sub New()
MyBase.New()
With Columns
.Add(FIELD_SomeField1, GetType(System.String)).DefaultValue = String.Empty
.Add(FIELD_SomeField2, GetType(System.Double)).DefaultValue = 0
End With
Dim keys(1) As DataColumn
keys(0) = Columns(FIELD_SomeField1)
TableName = TABLE_NAME
PrimaryKey = keys
End Sub
End Class
I'm currently working with EF, so in my razzle, I wrote something like this (yeah, it's vb):
Partial Public Class SomeTable1
Inherits DataTable
<Key()>
Friend Property SomePK1 As DataColumn
<Required(ErrorMessage:="SomeField1 is required.")>
<DataType(DataType.Text)>
Friend Property SomeField1 As DataColumn
<Required()>
<DataType(DataType.DateTime)>
Friend Property SomeField2 As DataColumn
...
Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
MyBase.New(info, context)
End Sub
Public Sub New()
MyBase.New()
SomeField2 = Date.Now
End Sub
End Class
I was dreaming on making something equivalent to the former dt and being completely compatible with the current data engine.
And then the type conversion error (system date to datacolumn) broke my hopes. I must admit that has been a hard weekend :)
So before I completely discard the change, Is there any way of writing a Typed datatable so it's equivalent to the code above but with some new goodies?
That's so ancient way of programming I can't find anything on the net.
Thanks in advance.
Not sure I'm following completely but it looks like you're defining FIELD_SomeField2 as a double
(This Line in first snippet)
.Add(FIELD_SomeField2, GetType(System.Double)).DefaultValue = 0
But then I see you're defining SomeField2 as a DateTime in your second snippet.
<Required()>
<DataType(DataType.DateTime)>
Friend Property SomeField2 As DataColumn
So maybe just a type mismatch...
I found how to do what I wanted. Perhaps involves some work, but it works.
Knowing that this is such an obsolete way of doing things, I'm posting there so others like me that are forced to maintain old programs can benefit.
The template for doing a typed datatable is the following:
Imports System.Data
Imports System.ComponentModel
Imports System.Runtime.Serialization
Imports System.Diagnostics
'''<summary>
'''Represents the strongly named DataTable class.
'''</summary>
<Global.System.Serializable(), _
Global.System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedTableSchema")> _
Partial Public Class tblMyTable
Inherits TypedTableBase(Of tblMyTableRow)
'Those are the StoredProcs names for (MANUAL) CRUD operations that the DBContext wrapper uses. (yuck! I hate thousands of them)
'Public Const COMMAND_SAVE As String = "sp_MyTable_Save"
'Public Const COMMAND_DELETE As String = "sp_MyTable_Delete"
'Public Const COMMAND_LOADBY_ID As String = "sp_MyTable_LoadBy_Id"
'Those are constants I maintain for untyped (but somewhat strong) compatibility
Public Const FIELD_pID As String = "pID"
Public Const FIELD_SomeOther As String = "SomeOtherField"
'Basic CRUD, uses company data as the app hot swapps DBs (one for company)
'Public Function Save(ByVal company As DataRow) As Short
' Return New Base(company).Update(Me, COMMAND_SAVE, COMMAND_DELETE)
'End Function
'Public Sub LoadByID(ByVal company As DataRow, Id As Integer)
' Me.Rows.Clear()
' Me.Merge(New Base(company).FillDataTable(Of tblMyTable)(COMMAND_LOADBY_ID, Id))
'End Sub
<DebuggerNonUserCodeAttribute()>
Private Sub InitClass()
Me.columnpID = New DataColumn(FIELD_pID, GetType(Integer), Nothing, MappingType.Element) With
{.AllowDBNull = False, .ReadOnly = True, .Unique = True,
.AutoIncrement = True, .AutoIncrementSeed = -1, .AutoIncrementStep = -1}
MyBase.Columns.Add(Me.columnpID)
Me.columnSomeOtherField = New DataColumn(FIELD_SomeOther, GetType(String), Nothing, MappingType.Element) With
{.MaxLength = 5, .AllowDBNull = False, .DefaultValue = String.Empty}
MyBase.Columns.Add(Me.columnSomeOtherField)
End Sub
Private columnpID As DataColumn
Private columnSomeOtherField As DataColumn
<DebuggerNonUserCodeAttribute()>
Public Sub New()
MyBase.New()
Me.TableName = "tblMyTable"
Me.BeginInit()
Me.InitClass()
Me.EndInit()
End Sub
<DebuggerNonUserCodeAttribute()>
Friend Sub New(ByVal table As DataTable)
MyBase.New()
Me.TableName = table.TableName
If (table.CaseSensitive <> table.DataSet.CaseSensitive) Then
Me.CaseSensitive = table.CaseSensitive
End If
If (table.Locale.ToString <> table.DataSet.Locale.ToString) Then
Me.Locale = table.Locale
End If
If (table.Namespace <> table.DataSet.Namespace) Then
Me.Namespace = table.Namespace
End If
Me.Prefix = table.Prefix
Me.MinimumCapacity = table.MinimumCapacity
End Sub
<DebuggerNonUserCodeAttribute()>
Protected Sub New(ByVal info As Global.System.Runtime.Serialization.SerializationInfo, ByVal context As Global.System.Runtime.Serialization.StreamingContext)
MyBase.New(info, context)
Me.InitVars()
End Sub
<DebuggerNonUserCodeAttribute()>
Public ReadOnly Property pIDColumn() As DataColumn
Get
Return Me.columnpID
End Get
End Property
<DebuggerNonUserCodeAttribute()>
Public ReadOnly Property SomeOtherFieldColumn() As DataColumn
Get
Return Me.columnSomeOtherField
End Get
End Property
<DebuggerNonUserCodeAttribute(), Browsable(False)>
Public ReadOnly Property Count() As Integer
Get
Return Me.Rows.Count
End Get
End Property
<DebuggerNonUserCodeAttribute()>
Default Public ReadOnly Property Item(ByVal index As Integer) As tblMyTableRow
Get
Return CType(Me.Rows(index), tblMyTableRow)
End Get
End Property
<DebuggerNonUserCodeAttribute()>
Public Overrides Function Clone() As DataTable
Dim cln As tblMyTable = CType(MyBase.Clone, tblMyTable)
cln.InitVars()
Return cln
End Function
<DebuggerNonUserCodeAttribute()>
Protected Overrides Function CreateInstance() As DataTable
Return New tblMyTable()
End Function
<DebuggerNonUserCodeAttribute()>
Friend Sub InitVars()
Me.columnpID = MyBase.Columns(FIELD_pID)
Me.columnSomeOtherField = MyBase.Columns(FIELD_SomeOther)
End Sub
<DebuggerNonUserCodeAttribute()>
Public Function NewtblMyTableRow() As tblMyTableRow
Return CType(Me.NewRow, tblMyTableRow)
End Function
<DebuggerNonUserCodeAttribute()>
Protected Overrides Function NewRowFromBuilder(ByVal builder As DataRowBuilder) As DataRow
Return New tblMyTableRow(builder)
End Function
<DebuggerNonUserCodeAttribute()>
Protected Overrides Function GetRowType() As Global.System.Type
Return GetType(tblMyTableRow)
End Function
<DebuggerNonUserCodeAttribute()>
Public Sub RemovetblMyTableRow(ByVal row As tblMyTableRow)
Me.Rows.Remove(row)
End Sub
End Class
'''<summary>
'''Represents strongly named DataRow class.
'''</summary>
Partial Public Class tblMyTableRow
Inherits DataRow
Private tabletblMyTable As tblMyTable
<DebuggerNonUserCodeAttribute()>
Friend Sub New(ByVal rb As DataRowBuilder)
MyBase.New(rb)
Me.tabletblMyTable = CType(Me.Table, tblMyTable)
End Sub
<DebuggerNonUserCodeAttribute()>
Public Property pID() As Integer
Get
Return CType(Me(Me.tabletblMyTable.pIDColumn), Integer)
End Get
Set(value As Integer)
Me(Me.tabletblMyTable.pIDColumn) = value
End Set
End Property
<DebuggerNonUserCodeAttribute()>
Public Property SomeOtherField() As String
Get
Return CType(Me(Me.tabletblMyTable.SomeOtherFieldColumn), String)
End Get
Set(value As String)
Me(Me.tabletblMyTable.SomeOtherFieldColumn) = value
End Set
End Property
End Class
That's all that you need. Perhaps It could be reduced, but then the dataset functions would not work as expected.
If you want that code, generated automagically for you by the ID (VS2010) you must follow those steps:
On server explorer, create the connection to your favorite DB
Right-click on top of your project and select adding a new element.
Just pick the dataset object template, the name is irrelevant. It will open in designer view.
Pick the table from the database and drag to the dataset designer.
Then... look at the class selector on top.
Unfold and locate [yourTableName]Datatable. Click on it.
It will jump to the said class in the DataSet1.designer.vb (cs) file.
The next class it's the row definition. Just copy-paste them into a new class file.
If you want a more complete datatable object, the next class below
the row class define events, and the delegate it's just above the
table def.
Simple and I tested it to work in conjunction of the remaining program, that uses untyped.
Perhaps it would be like polishing a turd, but I would like to add data annotations somewhere to do some client validations like in EF. And perhaps replace the columns constructor parameters for them. (but I caaan't)
good Luck.

VB.NET - Inherits System.Web.UI.WebControls.DropDownList doesn't call "Render" method

I have the following code, and when I put a Control of this type on a WebForm, it does not throw the Exception as you would expect it to, instead a <SELECT> is nicely rendered.
Imports System.ComponentModel
Imports System.Web.UI
<ToolboxData("<{0}:DropDownList runat=server></{0}:DropDownList>")> _
Public Class DropDownList
Inherits System.Web.UI.WebControls.DropDownList
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
Throw New Exception("Hello World")
End Sub
End Class
However, I have this code, and it works just fine (in that the Exception does get thrown):
Imports System.ComponentModel
Imports System.Web.UI
<ToolboxData("<{0}:TextBox runat=server></{0}:TextBox>")> _
Public Class TextBox
Inherits System.Web.UI.WebControls.TextBox
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
Throw New Exception("Hello World")
End Sub
End Class
Any ideas as to why?
Are you absolutely certain that you referenced the new class and not the standard asp.net one? That's the only reason I can think of that it wasn't called.
You might check the designer file to be absolutely certain. I have had numerous cases where I changed the control type in the source view, but the designer file was not updated until I went to the Design view and dirtied something.

Resources