Disable First and Last Buttons in Repeater - asp.net

public void Repeater1_ItemDatabound(Object Sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item)
{
if (e.Item.ItemIndex == 0)
{
Button b = e.Item.FindControl("btnmoveup") as Button;
b.Enabled = false;
}
DataView view = (DataView)SqlDataSource1.Select(DataSourceSelectArguments.Empty);
DataTable result = view.ToTable();
if (e.Item.ItemIndex == (result.Rows.Count)-1)
{
Button b2 = e.Item.FindControl("btnmovedown") as Button;
b2.Enabled = false;
}
}
}
I want to Grey out the first and the last buttons in my asp repeater. The first Button is disabled but the last is not. Can someone point out my error.?

Related

Dropdown Save in a gridview

I have a GRID that consist of columns that are populated and recently I have added some drop down columns as well to the grid. My drop down is populating with the options from the backend, but now I need to save those answers to the page itself, so the user can see it on the screen next time they arrive on the page.
GRID
protected void gvViolationsCited_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow || e.Row.RowType == DataControlRowType.Header)
{
TableCell idCell = GridViewFunctions.FindCellByDataField(e.Row, "ID");
idCell.Visible = false;
if (e.Row.RowType == DataControlRowType.DataRow)
{
ImageButton lb = (ImageButton)e.Row.FindControl("lbShowModalDialog");
long id = long.Parse(idCell.Text);
DropDownList hpvcriteria = (DropDownList)e.Row.FindControl("hpvcriteria");
hpvcriteria.DataSource = LookupDataLoaderService.Instance.LoadLookupData(LookupTables.HPV_VIOLATION_CODE);
hpvcriteria.DataBind();
}
}
}
private void PopulateViolationGrid(long caseID)
{
IList<EnforcementViolation> enforcementViolations = LovService.Instance.GetEnforcementLovList(caseID);
IEnumerator<EnforcementViolation> evEnumerator = enforcementViolations.GetEnumerator();
while (evEnumerator.MoveNext())
{
EnforcementViolation ev = evEnumerator.Current;
//txtOtherDocsViolated.Text += ev.Permit + " ";
}
gvViolationsCited.DataSource = GridViewFunctions.GenericListToDataTable<EnforcementViolation>(enforcementViolations);
gvViolationsCited.DataBind();
upnlViolationsCited.Update();
evEnumerator.Dispose();
}

How to detect repeater on OnCheckedChanged event of radio button

I have a nested repeater and there is a radiobutton in the inner one ( rptrSubscriptions ). What I want to do is to highlight the radio button that is selected and unhighlight the previous one .
There must be only one radio button selected between all of the radio buttons in the outer repeater .I also need to save the itemID of the selected one in a hidden field.
I have developed a method with the name of HighlightSubscription that will be called when user clicks on the radio button (OnCheckedChanged="HighlightSubscription") .
The problem is this, the system doesn't recognize rptrSubscriptions in HighlightSubscription method, I tried to use findcontrol but unfortunately there is no access to e.items in this method.
I also defined rptrSubscriptions as a public variable but it will be null too in this method.
I have copied the source of HighlightSubscription from HighlightBox that is a radio button inside a single repeater and it works fine as its definition is inside the designer,
but for the nested repeater the definition cant be in the designer as the system automatically removes it in compile time.
Any suggestion is highly appreciated.
protected void rptrSubscriptionGroups_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater rptrSubscriptions = (Repeater)e.Item.FindControl("rptrSubscriptions");
if (rptrSubscriptions != null)
{
RepeaterItem item = e.Item;
if (e.Item.ItemType == (ListItemType.Item) || e.Item.ItemType == (ListItemType.AlternatingItem))
{
DataTable SubscriptionTbl = SubscriptionsBind(SelectedLanguageID, SelectedPlatformID, SelectedCurrencyID, SelectedGroupID, 1);
rptrSubscriptions.DataSource = SubscriptionTbl;
rptrSubscriptions.DataBind();
}
}
}
protected void HighlightSubscription(object source, EventArgs e)
{
//find previous selected row
if (hiddenSelectedSubscriptionRowIndex.Value.Length > 0)
{
int rowIndex = int.Parse(hiddenSelectedSubscriptionRowIndex.Value);
//Repeater rptrSubscriptions = (Repeater)e.Item.FindControl("rptrSubscriptions");
RepeaterItem item = rptrSubscriptions.Items[rowIndex];
if (rptrSubscriptions != null)
{
// Uncheck Old Radio Button
RadioButton rbOld = (RadioButton)item.FindControl("rbBox");
rbOld.Attributes.CssStyle.Add("border-color", "lightgray");
rbOld.Attributes.CssStyle.Add("border-width", "1px");
rbOld.Checked = false;
}
}
RadioButton rb = source as RadioButton;
int CurrentrepeaterItemIndex = ((RepeaterItem)rb.NamingContainer).ItemIndex;
// save current row index in a hiddden field
hiddenSelectedSubscriptionRowIndex.Value = CurrentrepeaterItemIndex.ToString();
}
<asp:Repeater ID="rptrSubscriptionGroups" runat="server" OnItemDataBound="rptrSubscriptionGroups_ItemDataBound" OnItemCommand="rptrSubscriptionGroups_ItemCommand">
<ItemTemplate>
<asp:Repeater ID="rptrSubscriptions" runat="server" OnItemDataBound="rptrSubscriptions_ItemDataBound" OnItemCommand="rptrSubscriptions_ItemCommand">
<ItemTemplate>
<asp:RadioButton ID="rbSubscription" runat="server" OnCheckedChanged="HighlightSubscription" AutoPostBack="true"/>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
A little edit from me you can try this one :
protected void HighlightSubscription(object source, EventArgs e)
{
Repeater rptrSubscriptions = new Repeater();
foreach (RepeaterItem a in rptrSubscriptionGroups.Items)
{
rptrSubscriptions = (Repeater)a.FindControl("rptrSubscriptions");
}
//find previous selected row
if (hiddenSelectedSubscriptionRowIndex.Value.Length > 0)
{
int rowIndex = int.Parse(hiddenSelectedSubscriptionRowIndex.Value);
//Repeater rptrSubscriptions = (Repeater)e.Item.FindControl("rptrSubscriptions");
RepeaterItem item = rptrSubscriptions.Items[rowIndex];
if (rptrSubscriptions != null)
{
// Uncheck Old Radio Button
RadioButton rbOld = (RadioButton)item.FindControl("rbBox");
rbOld.Attributes.CssStyle.Add("border-color", "lightgray");
rbOld.Attributes.CssStyle.Add("border-width", "1px");
rbOld.Checked = false;
}
}
RadioButton rb = source as RadioButton;
int CurrentrepeaterItemIndex = ((RepeaterItem)rb.NamingContainer).ItemIndex;
// save current row index in a hiddden field
hiddenSelectedSubscriptionRowIndex.Value = CurrentrepeaterItemIndex.ToString();
}
Something like this:
protected void rptrSubscriptionGroups_ItemDataCreated(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
RepeaterItem item = e.Item;
RadioButton rb = (RadioButton)item.FindControl("rbSubscription");
rb.AutoPostBack = true;
rb.CheckedChanged += new EventHandler(rb_CheckChanged);
}
}
private void rb_CheckChanged(object sender, EventArgs e)
{
RadioButton rb = (RadioButton)sender;
if(rb.Checked == true){
HighlightSubscription();
}
}

How can I get the previous row in gridview rowdatabound?

I would like to check the previous row data if it is equal to --,
if it is not equal to -- then I would enable button in the next row
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (DataBinder.Eval(e.Row.DataItem, "time_start").ToString() == "--")
{
Button btn = ((Button)e.Row.FindControl("Edit_Button"));
btn.Enabled = false;
}
}
}
You can also do it like this using GridView1.Rows[e.Row.RowIndex - 1].
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridViewRow prevrow = GridView1.Rows[e.Row.RowIndex - 1];
if( prevrow.RowType == DataControlRowType.DataRow)
{
// Your code for manipulating prevrow
}
if (DataBinder.Eval(e.Row.DataItem, "time_start").ToString() == "--")
{
Button btn = ((Button)e.Row.FindControl("Edit_Button"));
btn.Enabled = false;
}
}
}
One way to do this is:
Create a field previousRow in your class, of type GridViewRow.
Initialize this field to null in the a GridView.DataBinding event handler. This event is fired when databinding starts, before any of the RowDataBound events fires.
In your GridView.RowDataBound event handler, do your processing (including comparing with previousRow), then set previousRow = e.Row.

How to add an extra row (containing a Button and corresponding event handler) to the GridView

This must be something that a lot of people have done. Basically, it's a custom GridView (i.e. inherited control) with the ability to update all rows at once. I've tried putting the "update all" button in various places (footer, pager, outside the grid), but it looks neatest (to me) when the button is in an extra row as the last row of the GridView.
NB: The pager row is not a suitable place for this button because this custom control could be used in a situation where paging is false. Similarly, the normal footer may be required for some other purpose (e.g. totals).
Here's my code for putting the button in the correct place (with apologies for the terse variables etc.):
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
//Add an extra row to the table...
if (_updateAllEnabled)
{
GridViewRow r = base.CreateRow(-1, -1, DataControlRowType.Footer, DataControlRowState.Normal);
Button btn = new Button();
TableCell c = new TableCell();
btn.ID = "UpdateAllButton"; // tried with and without this line
btn.Text = "Update All";
btn.Click += new EventHandler(UpdateAll);
r.Cells.Add(c);
c.Controls.Add(btn);
Table t = this.Controls[0] as Table;
c.ColumnSpan = this.Columns.Count;
t.Rows.Add(r);
}
}
This gives the appearance that I want, but the click event (UpdateAll) does not fire.
I assume that the stuff is being added too late in the life cycle (PreRender), but where else can I do this to ensure that the row is at the end of the GridView? I also thought that there might be trouble identifying the button, so I tried setting the ID. In any case, the ID in the generated HTML looks OK (consistent with "working" buttons in the pager row.
Is there a way for me to achieve this or am I attempting the impossible?
The best place to create your footer-controls is RowCreated since that's early enough in the lifecycle and also ensures that their recreated on every postback:
Footer approach:
protected void Grid_RowCreated(Object sender, GridViewRowEventArgs e) {
if(e.Row.RowType == DataControlRowType.Footer) {
Button btn = new Button();
TableCell c = new TableCell();
btn.ID = "UpdateAllButton";
btn.Text = "Update All";
btn.Click += new EventHandler(UpdateAll);
var firstCell=e.Row.Cells[0];
firstCell.ColumnSpan =e.Row.Cells.Count;
firstCell.Controls.Add(btn);
while(e.Row.Cells.Count > 1)e.Row.Cells.RemoveAt(e.Row.Cells.Count-1);
}
}
Of course you have to set ShowFooter to true:
<asp:GridView ID="GridView1"
ShowFooter="true"
OnRowCreated="Grid_RowCreated"
runat="server"
</asp:GridView>
Pager approach:
In my opinion this is the purpose of the FooterRow. But if you really want to ensure that your Button is in the very last row of a GridView(even below Pager as commented), i would try my next approach.
Here I'm using the pager for your costom control(s) by adding another TableRow to the PagerTable which inherits from Table.
protected void Grid_RowCreated(Object sender, GridViewRowEventArgs e) {
switch(e.Row.RowType){
case DataControlRowType.Pager:
Button btnUpdate = new Button();
btnUpdate.ID = "UpdateButton";
btnUpdate.Text = "Update";
btnUpdate.Click += new EventHandler(UpdateAll);
var tblPager = (Table)e.Row.Cells[ 0 ].Controls[ 0 ];
var row = new TableRow();
var cell = new TableCell();
cell.ColumnSpan = tblPager.Rows[ 0 ].Cells.Count;
cell.Controls.Add(btnUpdate);
row.Cells.Add(cell);
tblPager.Rows.Add(row);
break;
}
}
To ensure that the pager is visible even if only one page is shown(note that the real pager is invisible if PageSize==1):
protected void Grid_PreRender(object sender, EventArgs e){
GridView gv = (GridView)sender;
GridViewRow gvr = (GridViewRow)gv.BottomPagerRow;
if(gvr != null) {
gvr.Visible = true;
var tblPager = (Table)gvr.Cells[ 0 ].Controls[ 0 ];
//hide real pager if unnecessary
tblPager.Rows[ 0 ].Visible = GridView1.PageCount > 1;
}
}
Of course now you have to set AllowPaging=true:
<asp:GridView ID="GridView1"
AllowPaging="true"
PagerSettings-Mode="NumericFirstLast"
OnRowCreated="Grid_RowCreated"
OnPreRender="Grid_PreRender"
OnPageIndexChanging="Grid_PageChanging"
runat="server">
</asp:GridView>
Final approach(working for a custom GridView and all PagerPositions):
public PagerPosition OriginalPagerPosition{
get { return (PagerPosition)ViewState[ "OriginalPagerPosition" ]; }
set { ViewState[ "OriginalPagerPosition" ] = value; }
}
protected void Page_Load(object sender, EventArgs e){
if(!IsPostBack) OriginalPagerPosition = GridView1.PagerSettings.Position;
GridView1.PagerSettings.Position = PagerPosition.TopAndBottom;
GridView1.AllowPaging = true;
// databinding stuff ...
}
Keep the RowCreated the same as above in Pager approach.
Visibility of top/bottom pagers will be controlled in PreRender according to the OriginalPagerPosition property. Both pagers are created even with PagerPosition=TOP, the bottom pager is required for your additional control(s):
protected void Grid_PreRender(object sender, EventArgs e)
{
GridView gv = (GridView)sender;
GridViewRow tpr = (GridViewRow)gv.TopPagerRow;
GridViewRow bpr = (GridViewRow)gv.BottomPagerRow;
tpr.Visible = gv.PageCount > 1 && (OriginalPagerPosition == PagerPosition.Top || OriginalPagerPosition == PagerPosition.TopAndBottom);
bpr.Visible = true;
var tblBottomPager = (Table)bpr.Cells[ 0 ].Controls[ 0 ];
tblBottomPager.Rows[ 0 ].Visible = gv.PageCount > 1 && (OriginalPagerPosition == PagerPosition.Bottom || OriginalPagerPosition == PagerPosition.TopAndBottom);
var tblTopPager = (Table)tpr.Cells[ 0 ].Controls[ 0 ];
tblTopPager.Rows[1].Visible = false;
}
Note: if you are extending the GridView control, you have to replace all occurences of GridView1(my test-grid) with this.
It would be easy to add an extra row into the grid. But the difficulty in your requirement is that the GridView's RowCollection should not contain this row since that would be error-prone. It should also be the very last row even if paging is enabled. This is (afaik) not possible.
Hence i've chosen to extend the pager with this functionality.
I'll add this as separate answer since my other is already too detailed and describes two different ways(footer,pager) to add controls to a GridView without extending it.
This approach extends a GridView as in your own requirement and is similar to my other pager-approach. But it's cleaner and only adds the additional row to the BottomPager. It woks also for every setting(AllowPaging=false,Pager-Position: Top,Bottom,BottomTop):
[DefaultProperty("EnableUpdateAll")]
[ToolboxData("<{0}:UpdateGridView runat=server></{0}:UpdateGridView>")]
public class UpdateGridView : GridView
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("true")]
[Localizable(true)]
public bool EnableUpdateAll
{
get
{
Object val = ViewState["EnableUpdateAll"];
return ((val == null) ? true : (bool)val);
}
set
{
ViewState["EnableUpdateAll"] = value;
}
}
private bool OriginalAllowPaging
{
get
{
Object val = ViewState["OriginalAllowPaging"];
return (bool)val;
}
set
{
ViewState["OriginalAllowPaging"] = value;
}
}
private PagerPosition OriginalPagerPosition
{
get
{
Object val = ViewState["OriginalPagerPosition"];
return (PagerPosition)val;
}
set
{
ViewState["OriginalPagerPosition"] = value;
}
}
protected override void OnInit(System.EventArgs e)
{
if (ViewState["OriginalPagerPosition"] == null)
OriginalPagerPosition = base.PagerSettings.Position;
if(OriginalPagerPosition != PagerPosition.Bottom)
PagerSettings.Position=PagerPosition.TopAndBottom;
if (ViewState["OriginalAllowPaging"] == null)
OriginalAllowPaging = base.AllowPaging;
base.AllowPaging = true;
}
protected override void OnRowCreated(GridViewRowEventArgs e)
{
switch (e.Row.RowType)
{
case DataControlRowType.Pager:
//check if we are in BottomPager
if (this.Rows.Count != 0 && this.EnableUpdateAll)
{
Button btnUpdate = new Button();
btnUpdate.ID = "BtnUpdate";
btnUpdate.Text = "Update";
btnUpdate.Click += new EventHandler(UpdateAll);
var tblPager = (Table)e.Row.Cells[0].Controls[0];
var row = new TableRow();
var cell = new TableCell();
cell.ColumnSpan = tblPager.Rows[0].Cells.Count;
cell.Controls.Add(btnUpdate);
row.Cells.Add(cell);
tblPager.Rows.Add(row);
}
break;
}
}
protected override void OnPreRender(EventArgs e)
{
bool bottomPagerVisible =
OriginalAllowPaging &&
PageCount > 1 &&
(OriginalPagerPosition == PagerPosition.Bottom || OriginalPagerPosition == PagerPosition.TopAndBottom);
BottomPagerRow.Visible = bottomPagerVisible || EnableUpdateAll;
var tblBottomPager = (Table)BottomPagerRow.Cells[0].Controls[0];
tblBottomPager.Rows[0].Visible = bottomPagerVisible;
}
private void UpdateAll(Object sender, EventArgs e)
{
// do something...
}
}

How to enable disable buttons in datalist

I have got a datalist with some databound fields with 2 buttons. I want to enable disable button depending on the column(state) value of each row, so for instance if the value of state is 0 , the remove button should be disable and add button should be enabled similarly when the value of state is 1 , vice versa..
protected void dlEditCaravans_ItemDataBound(object sender, DataListItemEventArgs e)
{
Button addtoFeauture = e.Item.FindControl("btnAddToFeature") as Button;
Button removetoFeauture = e.Item.FindControl("btnRemoveFeature") as Button;
int id = Convert.ToInt32(dlEditCaravans.DataKeys[e.Item.ItemIndex]);
int check = caravans.GetfeautureValue(id);
if (check == 0)
{
addtoFeauture.Enabled = true;
}
else
{
removetoFeauture.Enabled = true;
}
}
I have tried something like above but it gives object reference not set to an instance error.
You need to use ItemDatabound event of Datalist
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
{
DataRow dr = ((DataRowView)e.Item.DataItem).Row;
if (Convert.ToBoolean(dr["StateColumnName"])
{
((Button)e.Item.FindControl("Button1")).Enable = True;
}
}
}
void DataListProduct_ItemDataBound(object sender, System.Web.UI.WebControls.DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
Button BT = e.Item.FindControl(“ButtonID“) as Button;
BT.Enable = True or false depends upon your condition
}
}

Resources