Highlighting and editing Grids - c#

I currently have a gridview that is populated via database through a c# method.
I wanted to know if there was a way to select the row when clicked anywhere on the row and not use the select button altogether. And then have the information from that row be sent back and populate another area on the webpage.
Is there a grid better than gridview for this? Should I outsource to jQuery? Or is gridview all I should need?

what you need to do is develop a row-clickable GridView. Best bet is to follow the instructions in the link. If your okay with VB, you can go along that route. A user has also converted it into C#, its in the comments section. Ill include it incase you dont see it.
Heres a link I have saved: http://aspadvice.com/blogs/joteke/archive/2006/01/07/14576.aspx
using System;
using System.ComponentModel;
using System.Configuration;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CustomGridView
{
/// <summary>
/// Summary description for ClickableGridView
/// </summary>
public class ClickableGridView : GridView
{
public string RowCssClass
{
get
{
string rowClass = (string)ViewState["rowClass"];
if (!string.IsNullOrEmpty(rowClass))
return rowClass;
else
return string.Empty;
}
set
{
ViewState["rowClass"] = value;
}
}
public string HoverRowCssClass
{
get
{
string hoverRowClass = (string)ViewState["hoverRowClass"];
if (!string.IsNullOrEmpty(hoverRowClass))
return hoverRowClass;
else
return string.Empty;
}
set
{
ViewState["hoverRowClass"] = value;
}
}
private static readonly object RowClickedEventKey = new object();
public event GridViewRowClicked RowClicked;
protected virtual void OnRowClicked(GridViewRowClickedEventArgs e)
{
if (RowClicked != null)
RowClicked(this, e);
}
protected override void RaisePostBackEvent(string eventArgument)
{
if (eventArgument.StartsWith("rc"))
{
int index = Int32.Parse(eventArgument.Substring(2));
GridViewRowClickedEventArgs args = new GridViewRowClickedEventArgs(Rows[index]);
OnRowClicked(args);
}
else
base.RaisePostBackEvent(eventArgument);
}
protected override void PrepareControlHierarchy()
{
base.PrepareControlHierarchy();
for (int i = 0; i < Rows.Count; i++)
{
string argsData = "rc" + Rows[i].RowIndex.ToString();
Rows[i].Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference(this, argsData));
if (RowCssClass != string.Empty)
Rows[i].Attributes.Add("onmouseout", "this.className='" + RowCssClass + "';");
if (HoverRowCssClass != string.Empty)
Rows[i].Attributes.Add("onmouseover", "this.className='" + HoverRowCssClass + "';");
}
}
}
public class GridViewRowClickedEventArgs : EventArgs
{
private GridViewRow _row;
public GridViewRowClickedEventArgs(GridViewRow aRow)
: base()
{
_row = aRow;
}
public GridViewRow Row
{
get
{ return _row; }
}
}
public delegate void GridViewRowClicked(object sender, GridViewRowClickedEventArgs args);
}

Related

How to add support of multiobject edits for PropertyGrid's custom property editor?

This is the simplest ever custom property editor that contains just a form with one more PropertyGrid:
using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms.Design;
namespace PageControls
{
public partial class PropertyGridEditor : Form
{
public object ObjectToEdit;
public delegate void PropertyValueChangedEventHandler(object sender, PropertyValueChangedEventArgs e);
public static event PropertyValueChangedEventHandler PropertyValueChangedStatic;
public event EventHandler<PropertyValueChangedEventArgs> PropertyValueChanged;
public PropertyGridEditor(object obj_to_edit)
{
InitializeComponent();
this.ObjectToEdit = obj_to_edit;
}
private void PropertyGridEditor_Load(object sender, EventArgs e)
{
this.prop_grid.SelectedObject = ObjectToEdit;
}
private void PropertyGridEditor_FormClosed(object sender, FormClosedEventArgs e)
{
this.DialogResult = System.Windows.Forms.DialogResult.OK;
}
private void prop_grid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
var evt = PropertyGridEditor.PropertyValueChangedStatic;
if (evt != null)
evt(s, e);
var evt2 = this.PropertyValueChanged;
if (evt2 != null)
evt2(s, e);
}
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class InnerPropertyGridEditor : UITypeEditor
{
public InnerPropertyGridEditor()
{
}
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
// Indicates that this editor can display a Form-based interface.
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
// Attempts to obtain an IWindowsFormsEditorService.
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (edSvc == null)
return null;
using (PropertyGridEditor form = new PropertyGridEditor(value)) //when two or more properties were selected the value is null :/
if (edSvc.ShowDialog(form) == DialogResult.OK)
return form.ObjectToEdit;
return value; // If OK was not pressed, return the original value
}
}
}
So, now I have a class:
class Test
{
public bool Prop1 { get; set; }
public bool Prop2 { get; set; }
}
And I have main class that has this Test class as property.
class MainClass
{
[Editor(typeof(InnerPropertyGridEditor), typeof(UITypeEditor))]
public Test test_prop { get; set; }
...
}
My main PropertyEditor supports multi selected objects.
So, I can select two or more MainClasses to edit their properties.
The problem is - when I do that and tries to edit test_prop InnerPropertyGridEditor appears empty, because of passed value is null.
Actually, I hoped it to be at least object[] so I can implement something.
Ok, in case if no one will ever answer this I will show the hacky solution I made:
using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using System.Reflection;
namespace PageControls
{
public partial class PropertyGridEditor : Form
{
public object Result;
public static event EventHandler<PropertyValueChangedEventArgs> PropertyValueChangedStatic;
public event EventHandler<PropertyValueChangedEventArgs> PropertyValueChanged;
public PropertyGridEditor(object[] obj_to_edit)
{
InitializeComponent();
this.prop_grid.SelectedObjects = obj_to_edit;
this.Result = obj_to_edit[0];
}
private void PropertyGridEditor_Load(object sender, EventArgs e)
{
}
private void PropertyGridEditor_FormClosed(object sender, FormClosedEventArgs e)
{
this.DialogResult = System.Windows.Forms.DialogResult.OK;
}
private void prop_grid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
var evt = PropertyGridEditor.PropertyValueChangedStatic;
if (evt != null)
evt(s, e);
var evt2 = this.PropertyValueChanged;
if (evt2 != null)
evt2(s, e);
}
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class InnerPropertyGridEditor : UITypeEditor
{
public InnerPropertyGridEditor()
{
}
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
// Indicates that this editor can display a Form-based interface.
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
// Attempts to obtain an IWindowsFormsEditorService.
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (edSvc == null)
return null;
object[] values = new object[context.Instance is object[] ? ((object[])context.Instance).Length : 1];
if (context.Instance is object[])
for (int i = 0; i < ((object[])context.Instance).Length; i++)
{
PropertyInfo pi = ((object[])context.Instance)[i].GetType().GetProperty(context.PropertyDescriptor.Name);
values[i] = pi != null ? pi.GetValue(((object[])context.Instance)[i], null) : null;
}
else
values[0] = value;
using (PropertyGridEditor form = new PropertyGridEditor(values))
if (edSvc.ShowDialog(form) == DialogResult.OK)
return form.Result;
return value; // If OK was not pressed, return the original value
}
}
}

get the values from checkboxes those were created dynamically C# JQuery Asp.net

I have these checkboxes those are created dynamically using C#. These are HTMLInputCheckboxes. They are kept under a panel called "panel_seat".
I want to get the values from these checkboxes to post them in database. How to do this? Either creating them as checkbox list or group?
If so please give me some code references please.
Jquery code:
$(document).ready(function () {
$("#btn_check").click(function () {
var str = "";
x = $("#frm").serializeArray();
str = JSON.stringify(x);
$('#<%=hdnSelectedTicket.ClientID %>').val(str);
});
});
Asp.net:
<asp:HiddenField ID="hdnSelectedTicket" runat="server" />
C# code: Using special dll for Json
using System.Web.Script.Serialization;
using Newtonsoft.Json;
namespace TestApp.components.seatfromdb
{
public class Test
{
public string name { get; set; }
public string value { get; set; }
}
public partial class seatfromdb : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btn_submit_Click(object sender, EventArgs e)
{
List<Test> myDeserializedObjList = (List<Test>)Newtonsoft.Json.JsonConvert.DeserializeObject(hdnSelectedTicket.Value, typeof(List<Test>));
int count = myDeserializedObjList.Count;
string[] chkarr = new string[count-4];
int j=0;
for (int i = 0; i < count; i++)
{
if (myDeserializedObjList[i].name.Substring(0, 6) == "check_")
{
chkarr[j] = myDeserializedObjList[i].name.Substring(6,1);
j++;
}
}
}
}
}
Checkbox group or list is not needed. I Used hidden field which carries the (stringified checkbox values) Json. charr[] array can be put into the database as by our need either as bytes or anything else.

Simple Custom Web Control

Hello I am designing a custom .net web control that inherits from the aspx dropdownlist.
The idea is to have a dropdownlist that will display year values up until the current year. I want to be able to set a "StartYear" property that the control can start from or else use a default date. I am able to create this control but it is always using the defult date. It seems I am unable to use the property setting in the aspx code in the code behind. My front end code is ....
<customControls:YearDropDownList StartYear="2000" ID="ddlYear" runat="server"/>
and the code behind is
using System;
using System.ComponentModel;
using System.Globalization;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace customControls {
[ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")]
[DefaultProperty("StartYear")]
public class YearDropDownList : DropDownList
{
public YearDropDownList() {
for (int i = Int32.Parse(StartYear); i <= DateTime.Now.Year; i++)
{
this.Items.Add(new ListItem(i.ToString(), i.ToString()));
}
}
public string StartYear {
get{
String s = (String)ViewState["StartYear"];
return ((s == null) ? "2009":s);
}
set{
ViewState["StartYear"] = value;
}
}
}
}
To my way of thinking, it doesn't make sense to regenerate the list in the constructor. At the time the control is instantiated, ViewState probably won't be populated yet (though I am not sure of this) and therefore you'll always get your default value being used.
Here's what I'd do:
[ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")]
[DefaultProperty("StartYear")]
public class YearDropDownList : DropDownList
{
public string StartYear
{
get
{
String s = (String)ViewState["StartYear"];
return ((s == null) ? "2009" : s);
}
set
{
ViewState["StartYear"] = value;
RegenerateList();
}
}
// Defer regenerating the list until as late as possible
protected void OnPreRender(EventArgs e)
{
RegenerateList();
base.OnPreRender(e);
}
public void RegenerateList()
{
// Remove any existing items.
this.Items.Clear();
for (int i = Int32.Parse(StartYear); i <= DateTime.Now.Year; i++)
{
this.Items.Add(new ListItem(i.ToString(), i.ToString()));
}
}
}
you need to regenerate the list when the property is set like so;
[ToolboxData("<{0}:YearDropDownList runat=\"server\" StartYear=\"[StartYear]\"></{0}:YearDropDownList>")]
[DefaultProperty("StartYear")]
public class YearDropDownList : DropDownList
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
RegenerateList();
}
public string StartYear
{
get
{
String s = (String)this.ViewState["StartYear"];
return s ?? "2009";
}
set
{
ViewState["StartYear"] = value;
RegenerateList();
}
}
public void RegenerateList()
{
Items.Clear();
for (int i = Int32.Parse(this.StartYear); i <= DateTime.Now.Year; i++)
{
this.Items.Add(new ListItem(i.ToString(), i.ToString()));
}
}
}
I have tested and verified the code above and it most definitely works. An interesting thing that I did notice was that I was able to reproduce your issue for a while in that the property setter was not being hit. I resolved this by right-clicking the solution and clicking Clean. After the solution was cleaned, I right-clicked on the solution again but this time selected Rebuild. That seemed to solve the property setter issue.

Checking To Make Sure My Object isn't Partially Initialized

I'm creating a simple application that takes a URL and a String and create the code for a hyperlink.
Here is my HyperLink Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LinkIt_
{
class HyperLink
{
private string url;
private string text;
public HyperLink()
{
}
public HyperLink(string url,string text)
{
this.Website = url;
this.Text = text;
}
public String Website
{
get
{
return url;
}
set
{
if (String.IsNullOrEmpty(value))
{
throw new ArgumentNullException("Must have URL!");
}
this.url = value;
}
}
public String Text
{
get
{
return text;
}
set
{
if (String.IsNullOrEmpty(value))
{
throw new ArgumentNullException("Must have Text!");
}
this.text = value;
}
}
public string addPoint()
{
return String.Format("<li>", url) + text + "</li>";
}
public override string ToString()
{
return String.Format("",url) + text + "" ;
}
}
}
Here is my Form Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace LinkIt_
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
HyperLink link;
try
{
if (chkPoint.Checked)
{
txtDisplay.Text = "";
link = new HyperLink(txtLink.Text, txtText.Text);
txtDisplay.Text = link.addPoint();
}
else
{
txtDisplay.Text = "";
link = new HyperLink(txtLink.Text, txtText.Text);
txtDisplay.Text = link.ToString();
}
}
catch (ArgumentNullException msg)
{
MessageBox.Show(msg.Message);
}
}
private void btnClear_Click(object sender, EventArgs e)
{
txtDisplay.Text = "";
txtLink.Text = "";
txtText.Text = "";
}
}
}
My Question:
How do I make sure that I don't create a partially initialized object?
If my code need correcting, Could someone help me ?
You could refactor your code to use properties with decreased accessor visibility.
This way the HyperLink objects can not be altered from outside the class (this is often a preferable attribute for data structures).
For example you could do something like this:
class HyperLink
{
public String Website{get; private set;}
public String Text {get; private set;}
public HyperLink(string url,string text)
{
if(string.isNullOrEmpty(url) || string.IsNullOrEmpty(text))
throw new ArgumentNullException("no partially intialized object allowed");
this.Website = url;
this.Text = text;
}
public string AddPoint()
{
return String.Format("<li>", url) + text + "</li>";
}
public override string ToString()
{
return String.Format("",url) + text + "" ;
}
}
Update to answer question in comments
Yes, it is perfectly reasonable to use the Getter/Setter from within the same object or class.
However, I advise to improve your usage of String.Format to the following:
String.Format("{1}",this.Link, this.Text);

Programically adding child controls to a asp.net composite control

Not found anything that directly answers my problem, so hopefully someone can shed some light on it.
I have two Composite Controls, lets call them BudgetTable and BudgetTableItem, where BudgetTable contains a list of BudgetTableItem.
So far everything works so long as I add new RowItems in the HTML View - when I add one programmatically it appears, but doesn't survive postback.
I can only assume I'm doing something boneheaded with ViewState, and would appreciate any pointers!
Thanks in advance.
The HTML:
<hea:BudgetTable runat="server" ID="btTest" MaximumFundingAvailable="7000" CssClass="bob">
<Items>
<hea:BudgetTableItem runat="server" Description="Test1" />
<hea:BudgetTableItem runat="server" Description="Test2" />
<hea:BudgetTableItem runat="server" Description="Test3" />
</Items>
</hea:BudgetTable>
The code behind:
[PersistenceMode(PersistenceMode.InnerProperty)]
[ParseChildren(true)]
public class BudgetTableItem : CompositeControl {
private TextBox _description = new TextBox();
private TextBox _cost = new TextBox();
private CheckBox _heaFunded = new CheckBox();
/*public delegate void AddRow();
public delegate void RemoveRow(BudgetTableItem item);
public event AddRow AddNewRow;
public event RemoveRow RemoveNewRow;*/
public string ItemName {
get {
var viewstate = ViewState["ItemName"];
return (viewstate is string) ? (string)viewstate : "default";
}
set {
ViewState["ItemName"] = value;
}
}
public bool ShowRemoveRow {
get {
var viewstate = ViewState["ShowRemoveRow"];
return (viewstate != null && viewstate is bool) ? (bool)viewstate : false;
}
set {
ViewState["ShowRemoveRow"] = value;
}
}
public bool ShowAddRow {
get {
var viewstate = ViewState["ShowAddRow"];
return (viewstate != null && viewstate is bool) ? (bool)viewstate : false;
}
set {
ViewState["ShowAddRow"] = value;
}
}
public string Description {
get {
return _description.Text;
}
set {
_description.Text = value;
}
}
public decimal Cost {
get {
decimal cost =0;
decimal.TryParse(_cost.Text, out cost);
return cost;
}
set {
_cost.Text = value.ToString();
}
}
public bool HeaFunded {
get {
return _heaFunded.Checked;
}
set {
_heaFunded.Checked = value;
}
}
protected override void CreateChildControls() {
Controls.Clear();
HtmlTableCell tableCell1 = new HtmlTableCell();
HtmlTableCell tableCell2 = new HtmlTableCell();
HtmlTableCell tableCell3 = new HtmlTableCell();
HtmlTableCell tableCell4 = new HtmlTableCell();
tableCell1.Attributes.Add("class", "col1");
tableCell2.Attributes.Add("class", "col2");
tableCell3.Attributes.Add("class", "col3");
tableCell4.Attributes.Add("class", "col4");
tableCell1.Controls.Add(_description);
tableCell2.Controls.Add(_cost);
tableCell3.Controls.Add(_heaFunded);
/*if (ShowAddRow || ShowRemoveRow) {
Button addNewButton = new Button();
addNewButton.Text = (ShowAddRow) ? "Add Row" : "Remove";
if (ShowAddRow) {
addNewButton.Click += new EventHandler(addNewButton_Click);
}
if (ShowRemoveRow) {
addNewButton.Click += new EventHandler(removeButton_Click);
}
tableCell4.Controls.Add(addNewButton);
}
else{*/
tableCell4.InnerHtml = " ";
//}
Controls.Add(tableCell1);
Controls.Add(tableCell2);
Controls.Add(tableCell3);
Controls.Add(tableCell4);
}
/*void addNewButton_Click(object sender, EventArgs e) {
if (AddNewRow != null) {
AddNewRow();
}
}*/
/*void removeButton_Click(object sender, EventArgs e) {
if (RemoveNewRow != null) {
RemoveNewRow(this);
}
}*/
protected override void RecreateChildControls() {
EnsureChildControls();
}
public override void RenderBeginTag(HtmlTextWriter writer) {
writer.Write("<tr>");
}
public override void RenderEndTag(HtmlTextWriter writer) {
writer.Write("</tr>");
}
}
Controls, custom or otherwise that require a ViewState and wish to receive events should be created in Init.
Http is stateless. Your entire page with all its controls is recreated on every postback. Controls that you add in the design view, are added to your designer.cs file, and created for you. When you add controls yourself, you must write code to recreate the controls on every PostBack that occurs later.
You can use the session to remember which controls were added by code and add them on later PostBacks.

Categories

Resources