For my ASP .NET webpage I am using a MySQL database with a TINYINT field to indicate a boolean (0/1) value.
Thanks to stackoverflow I was able to read the field value into a Listview as a asp:Checkbox.
<asp:CheckBox ID="freight_foundCheckbox" runat="server"
Checked='<%# Convert.ToBoolean(Eval("freight_found")) %>' />
What is challenging me now is how to reverse the transaction in the InsertItemTemplate or EditItemTemplate.
The listview textbox reads as:
<asp:TextBox ID="freight_foundTextBox" runat="server"
Text='<%# Bind("freight_found") %>' />
How do I bind a asp:Checkbox value back into the database as a integer value?
This web site link text was tremendously helpful in resolving this issue.
The key is to capture the value and convert it into a MySQL friendly format before writing to the database.
So for a insert set a ItemInserting event with this code:
CheckBox freightFound = (CheckBox)ListView2.InsertItem.FindControl("freight_foundCheckbox");
if (freightFound.Checked == true)
{
//true
e.Values["freight_found"] = 1;
}
else
{
//false
e.Values["freight_found"] = 0;
}
And then for a edit set a ItemUpdating event.
CheckBox freightFound = (CheckBox)ListView2.EditItem.FindControl("freight_foundCheckbox");
if (freightFound.Checked == true)
{
//true
e.NewValues["freight_found"] = 1;
}
else
{
//false
e.NewValues["freight_found"] = 0;
}
I know this is really old but I just spent a couple of hours trying to get this sorted.
in your UPDATE or INSERT statement you can use this
IF(?='True',1,0)
no need to change a bound checkboxfield to an item template or anything.
I'm not sure if it matters but I changed my parameter type to Boolean and as I now have it working I don't want to change it.
A little late here, but why not just bind it directly to the checkbox instead of a text field? No code behind handling needed that way. See below. MySQL tinyint(1) converts directly to .NET boolean and back when using the MySQL Connector/.NET.
<asp:CheckBox ID="freight_foundCheckbox" runat="server"
Checked='<%# Bind("freight_found") %>' />
Related
Googled variations of the title and everything was related to a null value.
I have an issue where the return value from Page.Request.Params["__EVENTTARGET"] duplicates the unique id of the control.
ctl00$MainContent$ActivityTabset$TabNewActivity$cbxActivityCode$ctl00$MainContent$ActivityTabset$TabNewActivity$cbxActivityCode
cbxActivityCode.UniqueID returns
ctl00$MainContent$ActivityTabset$TabNewActivity$cbxActivityCode
The following is the code that fails in the comparison. It is in the Page_Load event, and is the only code to execute right now if it is a postback.
string controlName = Page.Request.Params["__EVENTTARGET"];
if (cbxActivityCode.UniqueID == controlName)
{
ConfigureActivityUnits();
}
Here is the definition of the control
<obout:ComboBox ID="cbxActivityCode" runat="server"
DataSourceID="ObjectDataSourceDAOActivity"
FilterType="StartsWith" EmptyText="Select..."
AutoPostBack="true"
OnSelectedIndexChanged="cbxActivityCode_SelectedIndexChanged"
AllowCustomText="false" AutoValidate="true" DataValueField="Id"
DataTextField="Description" EnableViewState="true"
OpenOnFocus="true" MenuWidth="425" AllowEdit="False"
Width="300px">
</obout:ComboBox>
I am new to ASP.net and am wondering if it is possible one of the control attributes is causing this behavior?
Is it possibly a bug with the control?
Are there hooks in ASP.net where someone can manipulate a value which will effect Page.Request.Params["__EVENTTARGET"]? (This is a big messy legacy system, and I have no prior developers as a resource.)
If not any of the above, anyone have any ideas as to what could be causing this?
I need to hide /unhide the labels and textbox depending on db results , I tried something like this but it doesnt works, the condition should be like if the db field is empty for that field , then the label associated with that field should hidden (not visible) , following is the code i tried :
<asp:Label ID="lblBirth" Text="DOB:" runat="server" ViewStateMode="Disabled" CssClass="lbl" />
<asp:Label ID="DOB" runat="server" CssClass="lblResult" Visible='<%# Eval("Berth") == DBNull.Value %>'></asp:Label>
Code behind:
protected void showDetails(int makeID)
{// get all the details of the selected caravan and populate the empty fields
DataTable dt = new DataTable();
DataTableReader dtr = caravans.GetCaravanDetailsByMakeID(makeID);
while (dtr.Read())
{
//spec
string value = dtr["Price"].ToString();
lblModel.Text = dtr["model"].ToString();
birthResult.Text = dtr["Berth"].ToString(); }}
To make your aspx version work your control should be data bound to data source that contains "Berth" property. As I can see from code behind, you prefer to use c# to populate controls. In this case you may just do the following:
DOB.Visible = dtr["Berth"] == DBNull.Value;
I think that using data binding is more preferable solution.
I'm trying to use the regular expression validator for a numeric ID field. The field needs to be a required field of any number. Currently, I'm using:
="\d{1,}"
Shouldn't this make it so the user has to at least enter 1 digit?? If I hit the submit button with the field empty, it passes validation and posts back.. But if I enter non-numeric characters, it errors fine. If I wanted zero or more occurrences, I'd use: ="(\d{1,})?"
Why isn't this working? Do I need to use this in combination with a Required Field Validator? That would suck ><
Make sure you set the property ValidateEmptyText to true or else the CustomValidator will not fire for empty text.
EDIT: You can attach a javascript function to the CustomValidator to accomplish this since I don't think a RegularExpressionValidator will fire against an empty control. I have created a basic example to illustrate the solution:
<script type="text/javascript">
function CheckMyText(sender, args) {
var compare = RegExp("\\d{1,}");
args.IsValid = compare.test(args.Value);
return;
}
</script>
<asp:TextBox ID="txtTest" runat="server"></asp:TextBox>
<asp:Button ID="btnTest" runat="server" Text="Test" />
<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="Error!"
ControlToValidate="txtTest" ValidateEmptyText="true"
ClientValidationFunction="CheckMyText"></asp:CustomValidator>
I have tested it and it seems to work. Leave a comment if you require further assistance.
You still need to use a RequiredFieldValidator.
I'm not sure where the user is entering the IDs, but if the input field is TextBox control why don't you use something like this:
if (tbID.Text.Length != 0)
{
//Logic goes here
}
When user clicks submit, you need to make sure that not only empty strings are captured, below is a regex that looks for any whitespace(tab,space etc) + matches if character is not a digit(0-9)
Dim FoundMatch As Boolean
Try
FoundMatch = Regex.IsMatch(SubjectString, "\Dm/rld$/\s", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
'put your code here
Catch ex As ArgumentException
'syntax error in regular expression
End Try
I believe you'll need to use postback on your page, if you decide to use RequiredFieldValidator you can use above regex expression for that as well
Hth
In case someone is not using a CustomValidator then you can have a RequiredFieldValidator and RegularExpressionValidator for the same control. Found this solution here: http://forums.asp.net/t/1230931.aspx . Normally, this results in the error messages being displaced for the second validator but there is a way to fix that. You just have to set the Display property to dynamic for both the validators. Now the error messages for both the validators are displayed in the same location. Example code:
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server"
ErrorMessage="ErrorMsg" ControlToValidate="controlID"
ValidationExpression="regexExpression"
Display="Dynamic"></asp:RegularExpressionValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidator7" runat="server"
ErrorMessage="ErrorMsg" ControlToValidate="controlID"
Display="Dynamic"></asp:RequiredFieldValidator>`
I'm currently using a GridView and I want to set the CssClass for the Row depending on a property of the object that the row is being bound to.
I tried the following but it does not work (see comments):
<asp:GridView id="searchResultsGrid" runat="server" AllowPaging="true" PageSize="20" AutoGenerateColumns="false">
<!-- The following line doesn't work because apparently "Code blocks
aren't allowed in this context: -->
<RowStyle CssClass="<%#IIF(DataBinder.Eval(Container.DataItem,"NeedsAttention","red","") %>
<Columns>
<!--............-->
</Columns>
</asp:GridView>
Now I could simply handle the GridView's RowDataBound event and change the css class of the row there...but I'm trying to keep a clear separation between the UI and the page/business logic layers.
I have no idea how to accomplish this and I'm looking forward to hearing any suggestions.
Thanks,
-Frinny
You cannot do this in declarative markup.
Nearly all of GridView's declarative properties (including GridView.RowStyle) are grid-level settings rather than row-level. Apart from TemplateFields , they are not bound data containers, so they don't have access to the data in their rows.
If you want to keep this logic in the .aspx template, your only real option is to use template fields and manipulate their contents:
<asp:TemplateField>
<ItemTemplate>
<span class="<%# ((string)Eval("property3")) == "NeedsAttention" ? "red" : string.Empty %>">
<%# Eval("property1") %>
</span>
</ItemTemplate>
</asp:TemplateField>
Depending on what you want to do, this may be awkward - you don't have access to the containing <td> (or <tr> for that matter) and you'll have to repeat the formatting for each cell.
The GridView class goes to a lot of lengths to hide the details of HTML and styling from you. After all you could create a GridView control adapter that wouldn't even render as HTML tables. (Unlikely though that may be.)
So even though you're trying to avoid it, you're probably best off dealing with this in a OnRowDataBound handler - or use a Repeater (if that's appropriate).
I know it has been almost a year, but if anyone else is trying this, try to subclass the GridView.
public class GridViewCSSRowBindable : GridView
{
public string DataFieldRowCSSClass { get; set; }
protected override void OnRowDataBound(GridViewRowEventArgs e)
{
base.OnRowDataBound(e);
if (!string.IsNullOrEmpty(DataFieldRowCSSClass))
{
//This will throw an exception if the property does not exist on the data item:
string cssClassString = DataBinder.Eval(e.Row.DataItem, DataFieldRowCSSClass) as string;
if (!string.IsNullOrEmpty(cssClassString))
{
string sep = string.IsNullOrEmpty(e.Row.CssClass) ? string.Empty : " ";
e.Row.CssClass += sep + cssClassString;
}
}
}
}
And then in your Page:
<custom:GridViewCSSRowBindable ID="gvExample" runat="server" DataFieldRowCSSClass="RowCSS">
</custom:GridViewCSSRowBindable>
The objects being bound to this example GridView should have a public string RowCSS property.
If you haven't used inherited controls before, you might have to look up how to set that up in your project.
foreach (TableCell gvc in gvRowPhistry.Cells)
{
gvc.ForeColor = System.Drawing.Color.Blue;
}
Basically, i want my object back...
I have an Email object.
public class Email{
public string emailAddress;
public bool primary;
public int contactPoint;
public int databasePrimaryKey;
public Email(){}
}
In my usercontrol, i a list of Email objects.
public List<Email> EmailCollection;
And i'm binding this to a GridView inside my usercontrol.
if(this.EmailCollection.Count > 0){
this.GridView1.DataSource = EmailCollection;
this.GridView1.DataBind();
}
It would be really awesome, if i could get an Email object back out of the GridView later.
How do i do this?
I'm also binding only some of the Email object's properties to the GridView as well and they're put into Item Templates.
<Columns>
<asp:TemplateField HeaderText="Email Address">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text=<%# Eval("EmailAddress") %> Width=250px />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Primary">
<ItemTemplate>
<asp:CheckBox runat="server" Checked=<%# Eval("PrimaryEmail") %> />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Contact Point">
<ItemTemplate>
<CRM:QualDropDown runat="server" Type=ContactPoint InitialValue=<%# Eval("ContactPoint") %> />
</ItemTemplate>
</asp:TemplateField>
</Columns>
Can GridView even do this? Do i need to roll my own thing? It'd be really cool if it would do it for me.
To elaborate more.
I am saving the List collection into the viewstate.
What I'm eventually trying to get to, is there will be a Save button somewhere in the control, which when the event fires I'd like to create an Email object from a datarow in the GridView which to compare to my original List collection. Then if there's a change, then I'd update that row in the database. I was thinking that if I could put a List collection into a GridView, then perhaps I could get it right back out.
Perhaps I create a new constructor for my Email object which takes a DataRow? But then there's a lot of complexities that goes into that...
ASP.NET Databinding is a one-way operation in terms of object manipulation. However, the DataSource property will contain a reference to your EmailCollection throughout the response:
EmailCollection col = (EmailCollection)this.GridView1.DataSource;
But I have a feeling that what you really want is a control that manipulates your EmailCollection based on user input and retrieve it in the next request. Not even webforms can fake that kind of statefulness out of the box.
Well I ended up looping through my List EmailCollection, which was saved into the ViewState.
So in the page, a Save button is clicked, when the event is caught, I loop through my List Collection and grab the row from the GridView by index.
On the GridViewRow I have to use a GridView1.Rows[i].Cells[j].FindControl("myControl1") then get the appropriate value from it, be it a check box, text box, or drop down list.
I do see that a GridViewRow object has a DataItem property, which contains my Email object, but it's only available during the RowBound phase.
Unfortunately If/When i need to expand upon this Email Collection later, by adding or removing columns, it'll take a few steps.
protected void SaveButton_OnClick(object sender, EventArgs e){
for (int i = 0; i < this.EmailCollection.Count; i++)
{
Email email = this.EmailCollection[i];
GridViewRow row = this.GridView1.Rows[i];
string gv_emailAddress = ((TextBox)row.Cells[0].FindControl("EmailAddress")).Text;
if (email.EmailAddress != gv_emailAddress)
{
email.EmailAddress = gv_emailAddress;
email.Updated = true;
}
...
}
}
I'd still be open to more efficient solutions.
Just a thought, basically a roll your own but not that tricky to do:
Store the list that you use as a datasource in the viewstate or session, and have a hidden field in the gridview be the index or a key to the object that matches the row.
In other words, each row in the gridview "knows" which email object in the list that it is based on.
If you want to hold onto an object like this its easiest to use the viewstate, although you will be duplicating the data but for a small object it should be ok.
ViewState.Add("EmailObj", Email);
EMail email = (Email)ViewState["EmailObj"];