I have an aspx page like this:
<asp:TextBox ID="SearchInput" AutoPostBack="true" runat="server" />
<asp:Repeater ID="SelectUserListItemRepeater" runat="server">
<ItemTemplate>
<div><%# DataBinder.Eval(Container.DataItem, "Title")%></div>
</ItemTemplate>
</asp:Repeater>
And code behind like this.
using System;
using System.Linq;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Test : UserControl
{
private IList<TestItem> items;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
items = new List<TestItem>();
items.Add(new TestItem { Title="Lars"});
items.Add(new TestItem { Title = "Johan" });
items.Add(new TestItem { Title = "Bob" });
SelectUserListItemRepeater.DataSource = items;
SelectUserListItemRepeater.DataBind();
SearchInput.TextChanged += new EventHandler(SearchInput_TextChanged);
}
void SearchInput_TextChanged(object sender, EventArgs e)
{
var input = sender as TextBox;
var searchResult = items.Where(i => i.Title.Contains(input.Text));
/* Here I would like to show this search result in the Repeater,
* but what is the best way to do it?
*/
}
}
public class TestItem {
public string Title { get; set; }
}
What is to best way to implement search functionality in this kind of situation? I have one search text input and one repeater which renders a list of strings in DIV elements. When user writes some search key in a input then the repeater should only show those strings which contains the search key? How can I hide other RepeaterItems which doesn't contains the search key? or should I remove those RepeaterItems some how?
Try this:
void SearchInput_TextChanged(object sender, EventArgs e)
{
var input = sender as TextBox;
var searchResult = items.Where(i => i.Title.Contains(input.Text));
SelectUserListItemRepeater.DataSource = searchResult;
SelectUserListItemRepeater.DataBind();
}
Try this
private static List<TestItem> items = new List<TestItem>();
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
items = new List<TestItem>();
items.Add(new TestItem { Title="Lars"});
items.Add(new TestItem { Title = "Johan" });
items.Add(new TestItem { Title = "Bob" });
SearchInput.TextChanged += new EventHandler(SearchInput_TextChanged);
// bind repeater.
BindRepeater();
}
protected void SearchInput_TextChanged(object sender, EventArgs e)
{
var input = sender as TextBox;
items = items.Where(i => i.Title.Contains(input.Text)).ToList();
BindRepeater();
}
private void BindRepeater()
{
SelectUserListItemRepeater.DataSource = items;
SelectUserListItemRepeater.DataBind();
}
Related
I have created a composite control which houses a number of tiles (which are also custom controls). In my web page I want to catch the click-event of a tile, but I can't figure out how.
This is the TileButton: (the components can be designed dynamically, but I left this part out to keep it simple)
public class TileButton : LinkButton
{
public string Title { get; set; }
public string ImageUrl { get; set; }
private System.Web.UI.WebControls.Label title =
new System.Web.UI.WebControls.Label();
private Image image = new Image();
protected override void CreateChildControls()
{
base.CreateChildControls();
title.Text = Title;
image.ImageUrl = ImageUrl;
Controls.Add(title);
Controls.Add(image);
}
protected override void RenderContents(HtmlTextWriter writer)
{
RenderTitle(writer);
RenderImage(writer);
}
private void RenderImage(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Class,
"some css classes");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
image.RenderControl(writer);
writer.RenderEndTag();
}
private void RenderTitle(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Class,
"other css classes");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
writer.AddAttribute(HtmlTextWriterAttribute.Class,
"title css classes");
writer.RenderBeginTag(HtmlTextWriterTag.H6);
title.RenderControl(writer);
writer.RenderEndTag();
writer.RenderEndTag();
}
}
This is the composite control:
public class TilesControl : CompositeDataBoundControl
{
public List<TileButton> TileButtons { get; set; } =
new List<TileButton>();
protected override int CreateChildControls(IEnumerable datasource, bool databinding)
{
base.CreateChildControls();
int count = 0;
foreach (var item in datasource)
{
var tileButton = item as TileButton;
tileButton.ID = "tile" + count;
Controls.Add(tileButton);
TileButtons.Add(tileButton);
count++;
}
return count;
}
protected override void Render(HtmlTextWriter writer)
{
AddAttributesToRender(writer);
writer.AddAttribute(HtmlTextWriterAttribute.Class, "some css classes");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
foreach (var tile in TileButtons)
{
tile.CssClass = "button css classes";
tile.RenderControl(writer);
}
writer.RenderEndTag();
}
}
And in the page it's included like this:
<Something:TilesControl runat="server" ID="tiles1" DataSourceID="source1"></Something:TilesControl>
It all renders perfectly, the datasource is bound, but now I want the code behind to do something when a tileButton is clicked.
Extra: I would like the TileButton to have a property that defines WHAT to do when the button is clicked (some type of delegate?). Any pointers on that?
Thanks a lot.
It looks like you are binding a List<TileButton> as the DataSource of TilesControl. So you can bind a Click event to one of those buttons in the List before you bind them as the DataSource.
protected void Page_Load(object sender, EventArgs e)
{
//create a new tilescontrol instance
TilesControl tc = new TilesControl();
//create a list of tilebuttons
List<TileButton> buttons = new List<TileButton>();
//add some buttons for testing
for (int i = 0; i < 10; i++)
{
TileButton b = new TileButton();
b.ID = "TileButton" + i;
b.Title = "TileButton " + i;
//add the click event of a button here
b.Click += TileButton_Click;
//add the button to the list
buttons.Add(b);
}
//bind the list of buttons to the tilescontrol
tc.DataSource = buttons;
tc.DataBind();
//add the tilescontrol to the page
PlaceHolder1.Controls.Add(tc);
}
private void TileButton_Click(object sender, EventArgs e)
{
//display results
Label1.Text = ((TileButton)sender).Title + " Clicked!";
}
drop-down list in C#.net not showing the items it supposed to show!
i hv a drop-down list that suppose to show image names from a folder, but it is not doing that!
i dont have errors when launching the .aspx file!
buuuuuut when i get output there is only empty dropdown list!
this the ManageProducts.aspx codes are:
Name:
Type:
" SelectCommand="SELECT * FROM [ProductTypes] ORDER BY [Name]">
Price:
Image:
Description:
and this the behind codes:
using System;
using System.Collections;
using System.IO;
public partial class PagesNew_ManagementPages_ManageProducts : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack) //this baby makes the data not come every time the pg is refreshed ,
//postback=refresh page
GetImages();
}
private void GetImages()
{
try
{
//get all filepaths
string[] images = Directory.GetFiles(Server.MapPath("~/Img/Products/"));
//get all filenames and put them in a stupid array....yeah DSA days
ArrayList imageList = new ArrayList();
foreach (string image in images)
{
string imageName = image.Substring(image.LastIndexOf(#"\", StringComparison.Ordinal) + 1);
imageList.Add(imageName);
// see the Array in dd viwe datasource and refresh
ddImage.AppendDataBoundItems = true;
ddImage.DataBind();
}
}
catch (Exception e)
{
lblResult.Text = e.ToString();
}
}
protected void ddImage_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
You want to bind your datalist outside of the for loop.
ArrayList imageList = new ArrayList();
foreach (string image in images)
{
string imageName = image.Substring(image.LastIndexOf(#"\", StringComparison.Ordinal) + 1);
imageList.Add(imageName);
}
ddImage.DataSource = imageList;
ddImage.AppendDataBoundItems = true;
ddImage.DataBind();
On my aspx page has a button. I want to change its property dynamically.
For example:
A button which ID is Button1 and I want to change its property Visible to false.
On code behind have three variables hidefield = "Button1", property = "Visible" and value = false.
Is it possible to set the property Visible using the variables?
aspx:
<asp:Button ID="Button1" runat="server" Text="Button1" />
code behind:
protected void Page_Load(object sender, EventArgs e)
{
string hidefield = "Button1";
string property = "Visible";
bool value = false;
if (!IsPostBack)
{
Control myControl1 = FindControl(hidefield);
if (myControl1 != null)
{
myControl1.property = value; // <- I know this statement has error. Is there any way to set the property like this?
}
}
}
Using reflection, based on Set object property using reflection
using System.Reflection;
protected void Page_Load(object sender, EventArgs e)
{
string hidefield = "Button1";
string property = "Visible";
bool value = false;
if (!IsPostBack)
{
Control myControl1 = FindControl(hidefield);
if (myControl1 != null)
{
myControl.GetType().InvokeMember(hidefield ,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
Type.DefaultBinder, myControl, value);
}
}
}
It's pretty messy and not very human readable so therefore could have maintainablility issues.
how about this:
Button myControl1 = FindControl(hidefield) as Button;
if (myControl1 != null)
{
myControl1.Visible= value;
}
protected void Page_Load(object sender, EventArgs e)
{
string hidefield = "Button1";
string property = "Visible";
bool value = false;
if (!IsPostBack)
{
/* Use below two lines if you are using Master Page else you wouldnot be able to access your control */
ContentPlaceHolder MainContent = Page.Master.FindControl("MainContent") as ContentPlaceHolder;
Control myControl1 = MainContent.FindControl(hidefield);
if (myControl1 != null)
{
myControl1.GetType().GetProperty(property).SetValue(myControl1,value,null);
}
}
}
I am hitting an API and storing the returned parsed data to a List. Currently I am displaying the data in the ListView.
I am not able display the same list in a GridView. Can anyone guide me how to do it?
This is my aspx.cs code:
protected void Page_Load(object sender, EventArgs e)
{
ComodityList obj_comodity_in = (ComodityList)Session["comodity_list"];
Label1.Text = obj_comodity_in.status_code;
Label2.Text = obj_comodity_in.count.ToString();
//ComodityList obj_comodity_in = (ComodityList)Session["comodity_list"];
List<String> commodity_names = null;
getComodityNames(out commodity_names, obj_comodity_in);
ListView1.DataSource = commodity_names;
ListView1.DataBind();
}
private void getComodityNames(out List<String> commodity_names, ComodityList cl)
{
commodity_names = new List<string>();
foreach (Commodity c in cl.data)
{
commodity_names.Add(c.commodity);
commodity_names.Add(c.state);
commodity_names.Add(c.market);
commodity_names.Add(c.Maximum_Price.ToString());
commodity_names.Add(c.Minimum_Price.ToString());
commodity_names.Add(c.Modal_Price.ToString());
commodity_names.Add(c.origin);
commodity_names.Add(c.unit);
commodity_names.Add(c.variety);
}
}
Set AutoGenerateColumns property to true will help you.
Default.aspx:
<asp:GridView ID="GridView1" runat="server" Width="95%" autogeneratecolumns = "false">
Default.aspx.cs:
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
List<string> s = new List<string>() { "a", "b", "c" };
this.GridView1.DataSource = s;
this.GridView1.DataBind();
}
}
If you don't want to change the API (you still want to return a list of strings) and need to use a grid you could create a new class containing the properties you already had in Commodity and simply rehydrate the class using the lists string data. Each new 'Commodity' class could go in a new List<Commodity> and you can bind that to the grid.
On the other hand - it's probably better to reconsider what you are actually trying to achieve and then redesign the API if that is an option.
I populate web form with dynamic list of exams from database. I want user to enter examination marks for each exam. There is list of exam titles and textbox near each title.
I create list with repeater control (ViewState is disabled) :
<asp:Repeater ID="rptExams" runat="server" onitemdatabound="rptExams_ItemDataBound" >
<ItemTemplate>
<tr>
<td>
<asp:Literal runat="server" ID="ltTitle"/>
</td>
<td>
<asp:HiddenField runat="server" ID="hfId"/>
<asp:Textbox runat="server" ID="tbMark"/>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
And bind data to repeater on page_init:
class Exam
{
public int Id { get; set;}
public string Title { get; set;}
}
...
// this list is retrieved from database actually
Exam[] Exams = new Exam[]
{
new Exam { Id = 1, Title = "Math"},
new Exam { Id = 2, Title = "History"}
};
...
protected void Page_Init(object sender, EventArgs e)
{
rptExams.DataSource = Exams;
rptExams.DataBind();
}
So far so good. Then I have to retrieve data on postback. I have two ways but both of them looks ugly.
Idea is to store dynamically created databounded controls on ItemDataBoundEvent in Page_Init stage, and process their values in Page_Load stage. It looks like this:
private Dictionary<HiddenField, TextBox> Id2Mark = new Dictionary<HiddenField, TextBox>();
protected void rptExams_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
...
if (IsPostBack)
{
var tbMark = (TextBox)e.Item.FindControl("tbMark");
var hfId = (HiddenField)e.Item.FindControl("hfId");
// store dynamically created controls
Id2Mark.Add(hfId, tbMark);
}
...
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
foreach (var pair in Id2Mark)
{
int examId = Int32.Parse(pair.Key.Value);
string mark = pair.Value.Text;
// PROCESS
}
...
I'm completely sure there is a better way to retrieve data from dynamically created controls. Thank you in advance!
Here's how you can do it:
First, don't rebind the data on postback - it's not necessary. Only bind it on the first call of the page.
protected void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack){
rptExams.DataSource = Exams;
rptExams.DataBind();
}
}
You won't need the Dictionary neither.
Then, on a postback, you can get to the bound data as follows:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
foreach (RepeaterItem item in rptExams.Items)
{
HiddenField hfId = item.FindControl("hfId") as HiddenField;
TextBox tbMark = item.FindControl("tbMark") as TextBox;
int examId = Int32.Parse(hfId);
string mark = tbMark.Text;
// PROCESS
}
}
}