I am creating a gridView that allows adding new rows by adding the controls necessary for the insert into the FooterTemplate, but when the ObjectDataSource has no records, I add a dummy row as the FooterTemplate is only displayed when there is data.
How can I hide this dummy row? I have tried setting e.row.visible = false on RowDataBound but the row is still visible.
You could handle the gridview's databound event and hide the dummy row. (Don't forget to assign the event property in the aspx code):
protected void GridView1_DataBound(object sender, EventArgs e)
{
if (GridView1.Rows.Count == 1)
GridView1.Rows[0].Visible = false;
}
Please try the following
protected void GridView1_DataBound(object sender, EventArgs e)
{
GridView1.Rows[0].Visible = false;
}
I think this is what you need:
<asp:GridView ID="grid" runat="server" AutoGenerateColumns="false" ShowFooter="true" OnRowDataBound="OnRowDataBound">
<Columns>
<asp:TemplateField HeaderText="headertext">
<ItemTemplate>
itemtext
</ItemTemplate>
<FooterTemplate>
insert controls
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and the codebehind:
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["style"] = "display:none";
}
}
But I do not understand why you are adding your "insert controls" to the footer instead of placing them below the grid.
Maybe try:
e.Row.Height = Unit.Pixel(0);
This isnt the right answer but it might work in the meantime until you get the right answer.
Maybe use CSS to set display none?!
This is the incorrect usage of the GridView control. The GridView control has a special InsertRow which is where your controls should go.
GridView has a special property to access Footer Row, named "FooterRow"
Then, you cold try yourGrid.FooterRow.Visible = false;
I did this on a previous job, but since you can add rows, I always had it visible in the footer row. To make it so that the grid shows up, I bound an empty row of the type that is normally bound
dim row as Datarow = table.NewRow()
table.AddRow(row)
gridView.DataSource = table
gridView.Databind()
then it has all the columns and then you need. You can access the footer by pulling this:
'this will get the footer no matter how many rows there are in the grid.
Dim footer as Control = gridView.Controls(0).Controls(gridView.Controls(0).Controls.Count -1)
then to access any of the controls in the footer you would go and do a:
Dim cntl as Control = footer.FindControl(<Insert Control Name Here>)
I'd assume you'd be able to do a:
footer.Visible = false
to make the footer row invisible.
I hope this helps!
Edit I just figured out what you said. I basically delete the row when I add a new one, but to do this you need to check to see if there are any other rows, and if there are, check to see if there are values in it.
To delete the dummy row do something like this:
If mTable.Rows.Count = 1 AndAlso mTable.Rows(0)(<first column to check for null value>) Is DBNull.Value AndAlso mTable.Rows(0)(<second column>) Is DBNull.Value AndAlso mTable.Rows(0)(<thrid column>) Is DBNull.Value Then
mTable.Rows.Remove(mTable.Rows(0))
End If
mTable.Rows.Add(row)
gridView.Datasource = mTable
gridView.Databind()
Why are you not using the EmptyDataTemplate? It seems to work great even though I have only been using it for a couple days...
You should use DataKeyNames in your GridView:
<asp:GridView ID="GridView1" runat="server" DataKeyNames="FooID">
And then retrieve it on your code:
GridView1.DataKeys[0].Value.ToString()
Where "0" is the number of the row you want to get the "FooID"
To make it visible, just use:
Gridview.Rows.Item(i).Attributes.Add("style", "display:block")
And to make it invisible
Gridview.Rows.Item(i).Attributes.Add("style", "display:none")
If you do not want to display data when the column/row is null:
if (!String.IsNullOrEmpty(item.DataName))
{
e.Row.Visible = false;
}
It can easily be done by SQL
USE YourdatabaseName select * from TableName where Column_Name <> ''
Related
I'm adding some fields to a gridview dynamically in the gv.DataBinding event. I'm handling the selecting, paging and sorting in C#. Everything renders properly on screen and I can see the data is loaded into the gridview.
<asp:GridView ID="gvPulledBills" runat="server" AutoGenerateColumns="false"
OnDataBinding="gvPulledBills_DataBinding" OnRowDataBound="gvPulledBills_RowDataBound"
OnSelectedIndexChanged="gvPulledBills_SelectedIndexChanged"
AllowSorting="true" OnSorting="gvPulledBills_Sorting"
AllowPaging="true" PageSize="30" OnPageIndexChanging="gvPulledBills_PageIndexChanging"
DataKeyNames="Id" SkinID="gridviewGray">
In the gv.SelectedIndexChanged event, I need to retrieve the Id of the row selected. Id is stored in a HiddenField and the gv.DataKeyNames value is set to ID so I have two ways to retrieve it.
gv.SelectedValue works fine after the initial render. However, when selecting a row after paging/sorting, the gv.SelectedValue returns null. It behaves as if nothing was selected at all, even though my selected row markup is working correctly. Any suggestions on what I need to do to ensure the datakey is retrievable when binding columns dynamically?
Alternatively, I've tried accessing the hidden field directly rather than depending on the gv.SelectedValue...
protected void gvPulledBills_SelectedIndexChanged(object sender, EventArgs e)
{
GridView gv = (GridView)sender;
//var key = (int)gv.SelectedValue;
var index = gv.SelectedIndex - (gv.PageIndex * gv.PageSize);
var row = gv.Rows[index];
var hiddenField = (HiddenField)row.FindControl("hdnId");
var key = int.Parse(hiddenField.Value);
...
}
but the controls collections are empty in every cell, even for explicitly declared fields, even though there is data on the screen.
Explicit declaration
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="hdnId" runat="server" Value='<%# Eval("Id") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
Dynamic declaration
private TemplateField CreateTemplateField()
{
var controls = new List<Control>
{
{ CreateHiddenIdField() }
};
var tf = GridViewTools.CreateTemplateField(string.Empty, string.Empty, controls);
tf.ItemStyle.CssClass = "noRightBorder";
tf.HeaderStyle.CssClass = "noBorder";
return tf;
}
private static Control CreateHiddenIdField()
{
var hdn = new HiddenField();
hdn.ID = "hdnId";
hdn.Value = "'<%# Eval(\"Id\") %>'";
return hdn;
}
//in static class GridViewTools
public static TemplateField CreateTemplateField(string headerText, string sortExpression, List<Control> controls)
{
TemplateField tf = new TemplateField();
tf.HeaderText = headerText;
tf.SortExpression = sortExpression;
tf.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, controls);
return tf;
}
//... snippet that adds column to grid
var addColumns = new List<DataControlField>();
addColumns.Add(CreateTemplateField());
// add other columns
foreach (var column in addColumns)
{
gv.Columns.Add(column);
}
//...
Does anyone have any suggestions on how to get the SelectedValue populated when using code behind paging/sorting with dynamic columns? Or any suggestions on how to ensure the dynamically created field controls are populated and accessible in code behind?
I have many more columns added, mostly bound fields. I'm doing this to customize the column set based on drop-down fields elsewhere on the page. It's around 30 columns total and I would prefer not to add them all to the gridview, rather than just setting visibility on them all.
UPDATE SOLUTION
The final solution for this was:
var gv = (GridView)sender;
var rowIndex = gv.SelectedIndex - (gv.PageIndex * gv.PageSize);
var key = (int)gv.DataKeys[rowIndex]["Id"];
DisplayWorkDetail(key);
SelectedRow and SelectedValue are null at this point. Only SelectedIndex is populated. By converting the SelectedIndex to a RowIndex, I was able to retrieve the DataKey directly from the row.
I chose to use sender to make the code generic so I can easily extract it to a method for use with other GridViews.
I don't think you can use sender here.
but, while the Rowcommand has NOT changed the selected index, in that index changed event, it HAS changed. So, you can directly use/reference the control
eg:
GridViewRow myGv As GridViewRow = gvPulledBills.SelectedRow
and then:
myGv.RowIndex (get/use row index).
But, you already have the row, so:
hiddenField myField = (HiddenField)myGv.FindControl("hdnId");
int MyKey = int.Parse(myField.Value);
You can also I suppose use the Datakeys collection and not even have that hidden field.
So, you could do this:
GridViewRow myGv As GridViewRow = gvPulledBills.SelectedRow
int RowPK = (int)(gvPulledBills.DataKeys[myGv.RowIndex]["ID"]);
I have a .ascx user control on an .aspx page. When the user clicks a button, information is gathered and stored in the database. Then a Gridview is databinded and in the Gridview is a dropdownlist. This dropdownlist's Items are created dynamically based on the users previous input, now in the database. This is all good and the Gridview is displayed with the dropdownlist with the dynamically created Items.
The problem is on the postback for this dropdownlist. I obviously have to recreate the Gridview with the dynamically created Items in the dropdownlist. This does not work. The postback happens and calls the Page_Init and then the Page_InitComplete. This has the databind on the Gridview which calls the SectionGV_OnRowDataBound method. The dropdownlists are recreated. But the SectionDD_OnSelectedIndexChanged method is never hit and then the dropdownlist just reverts back to its original value. I can not change the dropdownlist's selected value.
.ASCX
<asp:GridView ID="MyGV" runat="server" AutoGenerateColumns="False" DataSourceID="MyDS" Width="100%" OnRowDataBound="MyGV_OnRowDataBound">
<Columns>
<asp:TemplateField >
<ItemTemplate>
<asp:DropDownList runat="server" ID="SectionDD" AppendDataBoundItems="True" AutoPostBack="True" OnSelectedIndexChanged="SectionDD_OnSelectedIndexChanged" >
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code Behind of .ASCX
protected void Page_Init(object sender,EventArgs e)
{
this.Page.InitComplete += Page_InitComplete;
}
private void Page_InitComplete(object sender, EventArgs e)
{
MyGV.DataBind();
}
protected void SectionDD_OnSelectedIndexChanged(object sender, EventArgs e)
{
}
protected void MyGV_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
using (EntitiesModel dbContext = new EntitiesModel())
{
// get array[][] array from database
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList sectionDd = (DropDownList)e.Row.FindControl("SectionDD");
sectionDd.Items.Clear();
if (array.Length == 3)
{
if(array[0][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[0][0], array[0][1]));
if(array[1][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[1][0], array[1][1]));
if(array[2][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[2][0], array[2][1]));
}
else if (array.Length == 2)
{
if (array[0][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[0][0], array[0][1]));
if (array[1][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[1][0], array[1][1]));
}
else if (array.Length == 1)
{
if (array[0][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[0][0], array[0][1]));
}
}
sectionDd.DataBind();
}
}
}
}
private void SaveToDB()
{
//save information to database
NOTE
This is one of many ways I have tried to solve this issue. The reason I have saved the information in the database is just a temporary fix. I just want to solve the issue outlined above and then I will add a ViewState solution.
First up, no, you do not have to re-create or load the grid again, or the dropdown list in the post back.
The user can type into the grid - change values, select drop downs. At that point you can loop all the grid rows and get/grab the dropdown values selected.
You CAN of course fire/trigger a event for the dropdown, but it not at all clear if you really need that event here.
If your grid is getting messed up on post-backs?, then it means you not limiting the load up in the FIRST page load - after that, it should not matter.
Say we have this grid markup:
<asp:GridView ID="MyGrid" runat="server" CssClass="table table-hover"
DataKeyNames="ID" AutoGenerateColumns="false" OnRowDataBound="MyGrid_RowDataBound" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="HotelName" HeaderText="Hotel Name" />
<asp:TemplateField HeaderText="City">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server"
DataTextField="City"
DataValueField="City"
>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Province" HeaderText="Province" />
</Columns>
</asp:GridView>
And of course non templated fields (such as the first few boundField - they appear in the .Cells collection. but for templated columns, you use findcontrol.
However, in EVERY and NEAR ALL web pages, as a general rule, you ONLY load + mess + create the grid ONE time, and you ONLY do this on the first page load - END OF STORY! You don't follow this rule, then you are in a world of hurt big time.
Ok, so lets load up the grid. Since we have a dropdown, then we have to fill that out on item data bound.
So, our code will look like this:
public DataTable rstCity = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
LoadGrid();
}
}
public void LoadGrid()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT City from City Order by City",
new SqlConnection(Properties.Settings.Default.TEST4)))
{
// locd city for drop down list
cmdSQL.Connection.Open();
rstCity.Load(cmdSQL.ExecuteReader());
// now load grid
cmdSQL.CommandText = "SELECT * from tblHotels ORDER BY HotelName";
DataTable rst = new DataTable();
rst.Load(cmdSQL.ExecuteReader());
MyGrid.DataSource = rst;
MyGrid.DataBind();
}
}
Note how I did scope the city table to the class level (no reason to load it over and over for each row - and after the first page load, it will go out of scope - we don't care - it will live during the first page load and the data binding.
Ok, now, lets do the item data bind for the grid.
We have this:
protected void MyGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList MyDrop = (DropDownList)e.Row.FindControl("DropDownList1");
MyDrop.DataSource = rstCity;
MyDrop.DataBind();
// get City from current data row source - set the drop to data row City
MyDrop.SelectedValue = ((DataRowView)e.Row.DataItem)["City"].ToString();
}
}
Ok, that's it. (note how the "dataitem" exists ONLY during data binding - a handy tip, since then you have use of the FULL data row - including PK values, and columns that you don't even include in the grid markup. But, once data binding is over, then DataItem can NOT be used - it only EVER exists during the bind process. But this information is VERY valuable, since you have full use of the Actual data SOURCE you used to bind. In above, I needed the City from that Row to set the drop list.
Ok, the output now looks like this:
Ok, at this point since we ONLY bind on first page load. The view state of that grid is 100% automatic handled by asp.net for you at this point in time.
You can drop other buttons on this form - post backs should NOT matter. The BIG lesson here is that gridview does persist (at least it will if we don't re-load it each time on post-back - you should NOT have to re-load).
Ok, next issue:
In most cases, I don't see the need for the dropdown list event in the grid?
So, you can as a general rule select and change any row combo. Once done, then you can get values of each row by looping the data grid rows - including that of dropdown selected.
However, Lets wire up the dropdown list event anyway.
tip of the day:
Since we can't select the dropdown and use the property sheet?
Then in markup do this:
You can in the markup type in OnSelectedIndexChanged=
WHEN you hit the "=" sign, note VERY close how intel-sense pops up a event create option:
So, click on CreateNewEvent - it "seems" like nothing occurs, but in fact if you flip over to code behind, you have a nice event stub created.
So lets put our code in that event - grab the row - show the value just slected.
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
// user changed the combo box
DropDownList MyDrop = (DropDownList)sender;
GridViewRow gRow = (GridViewRow)MyDrop.Parent.Parent;
Response.Write("<h2>Row index is = " + gRow.RowIndex.ToString() + "</h2>");
Response.Write("<h2>Hotel Name is = " + gRow.Cells[2].Text + "</h2>");
Response.Write("<h2>City from Drop selected = " + MyDrop.SelectedValue + "</h2>");
}
Of course we set auto post back = true in the drop markup also - right?
And note how we pick up the "sender", and then use .Parent.Parent to get the grid row that we are operating on. The first parent is some cell or some such.
I actually built recursive function to get that value, but for here we just used .parent.Parent (often with a extra markup, then you need to go op one more .parent).
Anyway, now say I select the last drop down in above, and change it.
I get this output:
In summary:
Only EVER load the grid - first page load - (you check IsPostBack).
You can have all kinds of additional post backs - the grid should survive and just be fine - no need to re-load at all. (GridView has built in viewstate).
Now, after I have fun, change the drop down on many rows?
I can loop the gridview - and any changes to that grid will persist.
In fact, if you make the columns text boxes (in templated fields), then you can tab around and edit almost like Excel, and again the values will persist for you, and they survive post backs. (and then you can send the whole grid of changes back to the database in one update command - I can show how to do this, but this post already has lots of good stuff anyway.
Now, having said the above, having done the above?
Well now that we have this working, then one can go back to building a custom user control - but if done right, it also should behave correctly, and should also survive post-backs.
Question pretty much says it all. On my aspx page I have a GridView and under Columns I have a bunch of BoundFields, one of which is a TemplateField
<asp:TemplateField HeaderText = "Status">
<ItemTemplate>
<asp:HyperLink ID = "HyperLink1" runat = "server" Target = "_blank"
NavigateUrl = '<%# Eval("URL") %>'
Text = '<%#Eval("Status") %>'>
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
Now, I want this Hyperlink to map to a different image, depending on what the text is evaluated to. For example, 'Success' displays a big ol' smiley face instead, 'Failed' displays a frowney face, and so on. How can I achieve this?
Thanks for looking.
You can put an image in the hyperlink like
<img src='/images/status/<%#Eval("Status") %>.jpg' />
and just make a different image for each status by name. Otherwise you'll probably have to do something on the DataBind event.
Try this
protected void myGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink HyperLink1 = e.Row.FindControl("HyperLink1");
if(SomeText == "Success")
HyperLink1.NavigateUrl = "Url to Smiley";
else
HyperLink1.NavigateUrl = "Url to Frowney";
}
}
HyperLink HyperLink1 = (HyperLink)e.Row.FindControl("HyperLink1");
switch (HyperLink1.Text)
{
case "Completed":
HyperLink1.ImageUrl = "Images\\Success.png";
HyperLink1.ToolTip = "Completed";
etc
The ToolTip property maps to the alternate text for the image.
Thanks to codingbiz for getting me started.
If you are trying to set the ImageUrl property I suggest using the RowDataBound event. The handler method could would look something like:
protected void questionsGridView_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
DataSourceDataType row;
HyperLink hyperLink1;
if (e.Row.RowType == DataControlRowType.DataRow & e.Row.DataItem is DataSourceDataType)
{
row = (DataSourceDataType)e.Row.DataItem;
hyperLink1 = (HyperLink)e.Row.FindControl("HyperLink1");
hyperLink1.ImageUrl = (row.IsSuccess) ? "~/images/success.png" : "~/images/failure.png";
}
}
Another trick I have used is altering the data object you are binding to to have a property which indicates the URL to use:
partial class DataSourceDataType
{
public string SuccessImgURL
{
get
{
return (IsSuccess) ? "~/images/success.png" : "~/images/failure.png";
}
}
}
Then you bind to that property.
Note: IsSuccess would need to be replaced with your own field name or boolean condition.
I often use this with LINQ to SQL objects, so adding properties can be done in a separate file using partial classes. This way you do not have to worry about the LINQ to SQL tools removing your additions.
how to find a command field control in the gridview.
in a method not in the row data bound.
so far i have used this coding but i cant find the control.
<asp:CommandField ButtonType="Image" ShowEditButton="True
HeaderText="Enter Leave"
EditImageUrl="~/IMAGES/edit-icon.gif">
<ItemStyle HorizontalAlign="Center" />
</asp:CommandField>
source code:
ImageButton edit = (ImageButton)EmployeeDetails.FindControl("Image");
edit.Enabled = false;
You can disable column itself with,
GridView1.AutoGenerateEditButton = false;
from code behind pages.
Or you can use ItemTemplate instead of CommandField,
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="id" CommandName="Edit" Text="Edit" />
</ItemTemplate>
</asp:TemplateField>
And at code behind you can iterate through rows of GridView and disable each LinkButton.
foreach(GridViewRow gvr in GridView1.Rows)
{
LinkButton row = gvr.FindControl("id") as LinkButton;
row.Enabled = false;
}
First Edit :
I tried my second solution and it works. However, make sure your GridView is filled before you use foreach. Otherwise, GridView.Rows.Count would probably be 0.
Second Edit :
This works for CommandField too. Replace 0 with the location of CommandField in your GridView.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[0].Enabled = false;
}
}
You miss to specify the row
Something like :
ImageButton edit = (ImageButton)EmployeeDetails.Rows[0].Cells[0].FindControl("Image");
edit.Enabled = false;
If you want to disable the column that contains the imageButton , you can do :
EmployeeDetails.Columns[0].Visible = false;
Try this:
try to hide controls at DataBound or RowDataBound event of GridView
protected void EmployeeDetails_DataBound(object sender, EventArgs e)
{
ImageButton edit = (ImageButton)EmployeeDetails.Row.Cells[0].FindControl("Image");
edit.Visible = false;
edit.Enabled = false; //OR use this line
}
particular column can be disabled in the following way
EmployeeDetails.Columns[0].Visible = false;
Hope this helps.
I had a similar issue. I simply disabled the view of the Column in BindData() function.
GridView1.Columns[0].Visible = false;
This worked for me, since my first column was Edit column and I have to enable it for specific users only.
Good luck!
Cast it as a DataControlFieldCell and then set Enabled to false.
Where: row.Controls[0] is your CommandField control
foreach (GridViewRow row in ManageDNXGridView.Rows)
{
DataControlFieldCell editable = (DataControlFieldCell)row.Controls[0];
editable.Enabled = false;
}
Is it possible to have a Checkbox that only shows up when Editing the last row of a GridView?
I have tried something like this in the EditItemTemplate:
<asp:CheckBox ID="chkNextDay" runat="server"
ToolTip="Is it a next-day departure?"
Enabled="true"
Checked='<%# DateTime.Parse(Eval("OutHour","{0:d}")).Date >
DateTime.Parse(Eval("InHour","{0:d}")).Date %>'/>
Then on code-behind I tried hiding it for rows other than the last one like this:
protected void grvOutHour_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView grvOutHour = (GridView)this.grvReport.Rows[grvReport.EditIndex].FindControl("grvOutHour");
TextBox txtBox = (TextBox)grvOutHour.Rows[e.NewEditIndex].FindControl("txtEditOutHour");
CheckBox nextDay = (CheckBox)grvOutHour.Rows[e.NewEditIndex].FindControl("chkNextDay");
if (grvOutHour.Rows.Count-1 != e.NewEditIndex)
nextDay.Visible = false;
}
This ALMOST worked, but the checkbox kept showing for all fields, I think because the RowDataBound is called AFTER RowEditing again so it renders the whole thing again :(
Any suggestions?
Thanks,
EtonB.
Use RowDataBound instead...
protected void grvOutHour_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowState == DataControlRowState.Edit)
{
GridView grid = (GridView)sender;
CheckBox nextDay = (CheckBox)e.Row.FindControl("chkNextDay");
nextDay.Visible = (e.Row.RowIndex == (grid.Rows.Count - 1));
}
}
You will need to handle hiding the checkbox in the RowDataBound event.
You'll need to determine what the last row is, and set the checkboxes visible property to true when that condition is true, obviously.
I guess it's more of a hack than an elegant solution, but I would probably just hide the other checkboxes via JavaScript if the condition is true.