Custom ListView to show EmptyDataTemplate and InsertItemTemplate at the same time - asp.net

It is known that the ListView control can't display both an EmptyDataTemplate and a InsertItemTemplate at the same time.
For my design style I need to be able to show both. I want to be able to show that no data exist and at the same time show a form to add new data.
I've already implemented various solutions, such as putting a PlaceHolder in my LayoutTemplate and then manually showing or hiding this PlaceHolder in the code-behind, depending on if there is data or not.
However, I would like a control that has this built-in capability in order to keep my code-behind light.
I believe there are only two ways to achieve what I want:
First way (preferred) is to write that custom control myself. I was thinking of deriving from ListView and overriding the function responsible for disabling the EmptyDataTemplate, but I have no experience with custom controls. And I'm not even sure it will work in the end.
Second way is to use a custom control found or purchased somewhere. I have not been able to find such control that has the same base capabilities as the ListView.
Has anybody any idea how to solve #1 and maybe #2?
Thank you.

Here is what I ended up doing:
public class MyListView : ListView
{
protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
{
int itemCount = base.CreateChildControls(dataSource, dataBinding);
if (this.InsertItemPosition != InsertItemPosition.None && itemCount == 0)
{
CreateEmptyDataItem();
}
return itemCount;
}
}
Works great!

I would go for your option 1: Create a custom control
Because you haven't specified a programming language I made one in VB.NET:
Public Class CustomListView
Inherits ListView
Public Sub CheckEmptyData() Handles Me.PreRender
If Me.Items.Count = 0 Then
Dim label As New Label
label.Text = "No data found <br/>"
Me.Controls.AddAt(0, label)
End If
End Sub
End Class
Just tested it and works perfectly, it can just replace an existing ListView.
As you can see it checks if there is any data and if not it inserts a label with the text "No data found". I haven't found an easy way to use the EmptyDataTemplate for this, that would be a better option but this might already work for you.
Another option is to hide the InsertItem (InsertItemPosition.None) if there is no data, and add a Button "Insert" to the EmptyDataTemplate that enables the InsertItemTemplate and therefore hides the EmptyDataTemplate.

I don't understand much of your requirement without a screen shot of what you are actually trying to achieve. Anyway, you may be able to achieve this interface with a combination of ListView+FormView or ListView+ a User Control. If you can provide any more info I may help further.

Related

Pass a variable to user control to determine display

Apologies if this is something really simple.
I've found various C# examples here, but I can't seem to get a VB version working.
I want to be able to pass a simple variable into a User Control to determine whether it shows a certain section of data.
It's basically a Customer Data form, and in some circumstances I need to show a line with the customers account number and sort code, and in some I don't, so my user control:
<controls:customerForm ID='customerForm' showBankDetails="no" runat='server' />
But I can't work out what to do with the showBankDetails variable in Code Behind to stop it from rendering that section, or simply hide it with a CSS snippet.
How do I access that variable in the code behind using VB.NET?
Normally I'd have optional stuff in a asp:panel on the page in the right spot, and in the page load or where ever, do something like:
me.OptionalStuffPanel.Visible = me.ShowBankDetails
ShowBankDetails would need to be defined as a public property of the page class:
private _ShowBankDetails as boolean
Public Property ShowBankDetails() As boolean
Get
Return _ShowBankDetails
End Get
Set(ByVal value As boolean)
_ShowBankDetails = value
End Set
End Property
If you want the property to appear in the property grid here is an article to show you how!
http://www.codeproject.com/KB/vb/using_propertygrid.aspx

How to conditionally make a DetailsView field read-only?

Say I have a DetailsView with a bunch of fields, and I want only certain kinds of users to edit a few of them. They're too few to split them into another DetailsView, so what I'm thinking is to find some way to only allow a user to edit them based on some code-behind logic, effectively making them read-only at will.
I feel it's important to mention that the fields are both TemplateFields, not normal BoundFields with ReadOnly properties.
Any ideas? For some reason the required functions don't jump at me from reading the documentation.
Oh and I need eveyone to see their specific values, I just want to restrict edit access to them.
Hrm apparently it was as simple as setting the EditItemTemplate property of the fields in question to null. Seems to be working fine so far!
Edit: A short code sample showing how I did it:
foreach (DataControlField field in dvDRDetails.Fields)
if (!fieldstoignore.Contains(field.HeaderText))
if (field is TemplateField)
((TemplateField)field).EditItemTemplate = null;
else if (field is BoundField)
((BoundField)field).ReadOnly = true;
Where fieldstoignore is an array of field headers that I always have set as editable. The rest fall in two categories: TemplateField that require the hack I discussed above and BoundField that have a ReadOnly property I can set.

Is there a reason that ASP.NET's CheckBoxList doesn't have a SelectedItems member?

Whenever I want to get selected items I have to loop through each item and see if it's selected. They even have a SelectedItem (no "s" at the end) member which seems odd for a CheckBoxList. It seems like a logical thing to have, does anyone know why they haven't added it?
Because they're not implementing the SelectedItem in CheckBoxList, but in ListControl that CheckBoxList inherits from. It can be argued that CheckBoxList needs to be taken back to source, as many of the ways that it is written are just not "correct" but that's a subjective argument. (this is the subject of a personal rant, I've just come across too many cases of CheckBoxList doing something obtusely and it's annoying, is all. Just not the way my mind works I suppose, and have never had others corroborate that it is annoying to them too.)
In addition to Dustin's en drachenstern's answers. You can roll your own :-)
public static IEnumerable<ListItem> SelectedItems(this CheckBoxList cbl)
{
return cbl.Items.Cast<ListItem>().Where(l=>l.Selected == true);
}
I would have to say that because the checkbox list renders individual HTML checkboxes that are not groupable like radio buttons the selected property needs to be evaluated on a item by item basis.
It is part of the documentation. Also note that the SelectedIndex will return the item with the lowest index.
The CheckBoxList control provides a
multi selection check box group that
can be dynamically generated with data
binding. It contains an Items
collection with members corresponding
to individual items in the list. To
determine which items are checked,
iterate through the collection and
test the Selected property of each
item in the list.
It's also fairly easy to subclass the CheckBoxList and implement this functionality yourself, which you can then re-use.
public class ExtendedCheckBoxList : CheckBoxList
{
public List<string> SelectedItems
{
get
{
return (from ListItem item in Items
where item.Selected
select item.Value).ToList();
}
}
}

flex3:How to override function set label of a button

Flex 3 question:
I trying here to avoid having to bind resources to all my components labels ( ie a button) and find a way to have this automated.
Problem:
It corrupts the layout in design mode to bind directly in the mxml label="{resourceManager.getString('myResources', 'submit')}" and makes the design view useless. but when declaring bindings elsewhere, in actionScript or via a bind tag, it is counter productive and prone to many errors and miss.
Proposition:
I would like to create my own button that automatically invoke resources to localize a button label. So the author puts "Submit" in the mxml description of my button, and when running it would take the value of the label ie "submit" and use resourceManager.getString('myResources', 'submit').
but I can't find the way to override the set label function, Is it possible if yes how? else how can I go about it?
Maybe I am missing an essential process here that would make the use of resources more elegant, as well as how to override such thing as a button's label.
Thanks for your advices.
Create a component called MyButton, extending Button. Then use this:
override public function set label(value:String):void {
super.label = resourceManager.getString('myResources', value) || value;
}
Assuming the resource manager returns "null" or "undefined" this will work, and will only replace the value if it exists in "myResources".
If you don't want to override every component you need to do this with, then you can add a FlexEvent.CREATION_COMPLETE event on every component. Then use a single generic function to do your label localization.

Setting Focus with ASP.NET AJAX Control Toolkit

I'm using the AutoComplete control from the ASP.NET AJAX Control Toolkit and I'm experiencing an issue where the AutoComplete does not populate when I set the focus to the assigned textbox.
I've tried setting the focus in the Page_Load, Page_PreRender, and Page_Init events and the focus is set properly but the AutoComplete does not work. If I don't set the focus, everything works fine but I'd like to set it so the users don't have that extra click.
Is there a special place I need to set the focus or something else I need to do to make this work? Thanks.
We had exactly the same problem. What we had to do is write a script at the bottom of the page that quickly blurs then refocuses to the textbox. You can have a look at the (terribly hacky) solution here: http://www.drive.com.au
The textbox id is MainSearchBox_SearchTextBox. Have a look at about line 586 & you can see where I'm wiring up all the events (I'm actually using prototype for this bit.
Basically on the focus event of the textbox I set a global var called textBoxHasFocus to true and on the blur event I set it to false. The on the load event of the page I call this script:
if (textBoxHasFocus) {
$get("MainSearchBox_SearchTextBox").blur();
$get("MainSearchBox_SearchTextBox").focus();
}
This resets the textbox. It's really dodgy, but it's the only solution I could find
this is waste , its simple
this is what you need to do
controlId.focus(); in C#
controlID.focus() in VB
place this in page load or button_click section
eg. panel1.focus(); if panel1 has model popup extender attached to it, then we put this code in page load section
How are you setting focus? I haven't tried the specific scenario you've suggested, but here's how I set focus to my controls:
Public Sub SetFocus(ByVal ctrl As Control)
Dim sb As New System.Text.StringBuilder
Dim p As Control
p = ctrl.Parent
While (Not (p.GetType() Is GetType(System.Web.UI.HtmlControls.HtmlForm)))
p = p.Parent
End While
With sb
.Append("<script language='JavaScript'>")
.Append("function SetFocus()")
.Append("{")
.Append("document.")
.Append(p.ClientID)
.Append("['")
.Append(ctrl.UniqueID)
.Append("'].focus();")
.Append("}")
.Append("window.onload = SetFocus;")
.Append("")
.Append("</script")
.Append(">")
End With
ctrl.Page.RegisterClientScriptBlock("SetFocus", sb.ToString())
End Sub
So, I'm not sure what method you're using, but if it's different than mine, give that a shot and see if you still have a problem or not.
What I normally do is register a clientside script to run the below setFocusTimeout method from my codebehind method. When this runs, it waits some small amount of time and then calls the method that actually sets focus (setFocus). It's terribly hackish, but it seems you have to go a route like this to stop AJAX from stealing your focus.
function setFocusTimeout(controlID) {
focusControlID = controlID;
setTimeout("setFocus(focusControlID)", 100);
}
function setFocus() {
document.getElementById(focusControlID).focus();
}
I found the answers from Glenn Slaven and from Kris/Alex to get me closer to a solution to my particular problem with setting focus on an ASP.NET TextBox control that had an AutoCompleteExtender attached. The document.getElementById(focusControlID).focus() kept throwing a javascript error that implied document.getElementById was returning a null object. The focusControlID variable was returning the correct runtime ClientID value for the TextBox control. But for whatever reason, the document.getElementById function didn't like it.
My solution was to throw jQuery into the mix, as I was already using it to paint the background of any control that had focus, plus forcing the Enter key to tab through the form instead of firing a postback.
My setFocus function ended up looking like this:
function setFocus(focusControlID) {
$('#' + focusControlID).blur();
$('#' + focusControlID).focus();
}
This got rid of the javascript runtime error, put focus on the desired TextBox control, and placed the cursor within the control as well. Without first blurring then focusing, the control would be highlighted as if it had focus, but the cursor would not be sitting in the control yet. The user would still have to click inside the control to begin editing, which would be an UX annoyance.
I also had to increase the timeout from 100 to 300. Your mileage my vary...
I agree with everyone that this is a hack. But from the end-user's perspective, they don't see this code. The hack for them is if they have to manually click inside the control instead of just being automatically placed inside the control already and typing the first few letters to trigger the auto lookup functionality. So, hats off to all who provided their hacks.
I hope this is helpful to someone else.

Resources