在ItemBound事件中if (e.Item.ItemIndex != -1)
{
if (e.Item.cell[0].Text == "1")
{
e.Item.Cell[0].Text ="Yes";
}
else
{
e.Item.Cell[0].Text = "NO";
}
}
{
if (e.Item.cell[0].Text == "1")
{
e.Item.Cell[0].Text ="Yes";
}
else
{
e.Item.Cell[0].Text = "NO";
}
}
解决的办法就是使用
Binding.Format 事件
和
Binding.Parse 事件
不过说实话,在我看《ado.net 技术内幕》之前也不知道可以这样来解决。下面的示例创建一个 Binding,向 Parse 事件和 Format 事件添加 ConvertEventHandler 委托,并通过 DataBindings 属性向 TextBox 控件的 BindingsCollection 添加 Binding。添加到 Format 事件的 DecimalToCurrencyString 事件委托使用 ToString 方法将绑定值(Decimal 类型)格式化为货币。添加到 Parse 事件的 CurrencyStringToDecimal 事件委托将控件所显示的值回转为 Decimal 类型。private void DecimalToCurrencyString(object sender, ConvertEventArgs cevent)
{
// The method converts only to string type. Test this using the DesiredType.
if(cevent.DesiredType != typeof(string)) return; // Use the ToString method to format the value as currency ("c").
cevent.Value = ((decimal) cevent.Value).ToString("c");
}private void CurrencyStringToDecimal(object sender, ConvertEventArgs cevent)
{
// The method converts back to decimal type only.
if(cevent.DesiredType != typeof(decimal)) return; // Converts the string back to decimal using the static Parse method.
cevent.Value = Decimal.Parse(cevent.Value.ToString(),
NumberStyles.Currency, null);
}private void BindControl()
{
// Creates the binding first. The OrderAmount is typed as Decimal.
Binding b = new Binding
("Text", ds, "customers.custToOrders.OrderAmount");
// Add the delegates to the event.
b.Format += new ConvertEventHandler(DecimalToCurrencyString);
b.Parse += new ConvertEventHandler(CurrencyStringToDecimal);
text1.DataBindings.Add(b);
}
<asp:TemplateColumn>
<ItemTemplate>
<%#(0 == Convert.ToInt32(DataBinder.Eval(Container.DataItem, "xx"))) ? "未完成" : "完成"%>
</ItemTemplate>
</asp:TemplateColumn>复杂情况
<asp:TemplateColumn>
<ItemTemplate>
<%# getxxName(DataBinder.Eval(Container.DataItem, "xx"))%>
</ItemTemplate>
</asp:TemplateColumn>
后台代码
protected static string getxxName(object xx)
{
if(xx != DBNull)
{
return (0 == Convert.ToInt32(xx)) ? "未完成" : "完成";
}
return "";
}
如果"未完成" : "完成"来自与另一张表用DataReleation创建DataColumn
简单的用DataColumn.Expression的条件判断
for (int i=0;i<objDS.Tables["admin"].Rows.Count;i++)
{
if (objDS.Tables["admin"].Rows[i]["username"].ToString==1)
objDS.Tables["admin"].Rows[i]["username"] = "完成";
else
objDS.Tables["admin"].Rows[i]["username"] = "未完成";
}
在后台定方法
public string DigitalToString(string pValue)
{
if(pValue == "1")
{
return "完成";
}
return "未完成";
}
在你的DataGrid 的Update事件中写
Label lbl = (Label)e.Item.FindControl("lbl");
string mValue = "0";
if(lbl.Text.Trim() == "完成")
mValue ="1"
然后用这张表作为内嵌在DataGrid中的Combobox的数据源
部分代码如下://创建离港标志虚拟表
DataTable dtLgbz=new DataTable();
dtLgbz.Columns.Add(new DataColumn("id",typeof(System.Int32)));
dtLgbz.Columns.Add(new DataColumn("des",typeof(System.String)));DataRow r1=dtLgbz.NewRow();
r1["id"]=0;
r1["des"]="否";
dtLgbz.Rows.Add(r1);DataRow r2=dtLgbz.NewRow();
r2["id"]=1;
r2["des"]="是";
dtLgbz.Rows.Add(r2);//创建二程船虚拟表
DataTable dtEcc=new DataTable();
dtEcc.Columns.Add(new DataColumn("id",typeof(System.Int32)));
dtEcc.Columns.Add(new DataColumn("des",typeof(System.String)));DataRow r11=dtEcc.NewRow();
r11["id"]=0;
r11["des"]="非二程船";
dtEcc.Rows.Add(r11);DataRow r22=dtEcc.NewRow();
r22["id"]=1;
r22["des"]="二程船";
dtEcc.Rows.Add(r22);
ss_manage.MyComboColumn lgbz = new MyComboColumn(dtLgbz,"des","id",false);
lgbz.MappingName = "LGBZ";
lgbz.HeaderText = "录毕否";
lgbz.Width=75;
width+=lgbz.Width;
dgts.GridColumnStyles.Add(lgbz);
ss_manage.MyComboColumn ecc = new MyComboColumn(dtEcc,"des","id",false);
ecc.MappingName = "ECC";
ecc.HeaderText = "是否二程船";
ecc.Width=this.dataGrid2.Width-this.dataGrid2.RowHeaderWidth-width;
dgts.GridColumnStyles.Add(ecc);要是用自定义列样式。
下面是内嵌Combobox的列样式的源代码
using System.Data;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;namespace ss_manage
{
/// <summary>
/// This DataGrid Column class implements a ComboBox Column. The combo box is fed from a
/// table containing an collection of value objects and a string descriptor (the displayed
/// element). On losing focus, the combo box the current cell in the associated DataGrid
/// is updated with the current selected value object
/// </summary>
public class MyComboColumn : System.Windows.Forms.DataGridTextBoxColumn
{
// each column shares a single combobox
public ComboBox _cboColumn;
// data we save when the column is instantiated (no provision for subsequent rebinds)
private object _objSource;
private string _strMember;
private string _strValue;
// remember if we have bound the combobox to the parent datagrid control
private bool _bIsComboBound = false;
// data that describes the background and foreground colors used to paint the cell when not in edit mode
private Brush _backBrush = null;
private Brush _foreBrush = null; // information picked up and held when we start to edit the source table
private int _iRowNum;
private CurrencyManager _cmSource; /// <summary>
/// initialize the combobox column and take note of the data source/member/value used to fill the combobox
/// </summary>
/// <param name="objSource">bind Source for the combobox (typical is a DataTable object)</param>
/// <param name="strMember">bind for the combobox DisplayMember (typical is a Column Name within the Source)</param>
/// <param name="strValue">bind for the combobox ValueMember (typical is a Column Name within the Source)</param>
public MyComboColumn(object objSource, string strMember, string strValue, bool bUseDropDownList)
{
_objSource = objSource;
_strMember = strMember;
_strValue = strValue; // create a new combobox object
_cboColumn = new ComboBox();
// set the data link to the source, member and value displayed by this combobox
_cboColumn.DataSource = _objSource;
_cboColumn.DisplayMember = _strMember;
_cboColumn.ValueMember = _strValue;
if (bUseDropDownList == true)
{
// we cannot create new countries through this column so disallow editing by making the combo a drop-down list
_cboColumn.DropDownStyle = ComboBoxStyle.DropDownList;
// Setting ReadOnly changes the behavior of the column so the 'leave' event fires whenever we
// change cell. The default behavior will not fire the 'leave' event when we up-arrow or
// down-arrow to the next row.
this.ReadOnly = true;
}
else
{
// because this is not an edit-through combo we are going to suppress key-strokes.
// notice this routine does not affect navigation or delete keys. The delete key
// allows us to select the null data value for this row
_cboColumn.KeyPress += new KeyPressEventHandler(_cboColumn_KeyPress);
this._cboColumn.DropDownStyle=ComboBoxStyle.Simple;
this.ReadOnly=true;
}
// we need to know when the combo box is getting closed so we can update the source data and
// hide the combobox control
_cboColumn.Leave += new EventHandler(cboColumn_Leave);
// make sure the combobox is invisible until we've set its correct position and dimensions
_cboColumn.Visible = false;
this.TextBox.MouseMove+= new MouseEventHandler(TextBox_MouseMove);
} private void _cboColumn_KeyPress(object sender, KeyPressEventArgs e)
{
// all key events as handled to block editing of combobox entries
e.Handled = true;
} protected override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
{
// the navigation path to the datagrid only exists after the column is added to the Styles
if (_bIsComboBound == false)
{
_bIsComboBound = true;
// important step here if we want to properly handle key events! the next step cannot
// be performed until the object is bound to the DataGrid (or an Exception must occur)
this.DataGridTableStyle.DataGrid.Controls.Add(_cboColumn);
}
// this data is used when the combo box loses focus
_iRowNum = rowNum;
_cmSource = source;
// synchronize the font size to the text box
_cboColumn.Font = this.TextBox.Font;
// we need to retrieve the current value and use this to set the combo box ahead of displaying it
object anObj = this.GetColumnValueAtRow(source, rowNum); // set the combobox to the dimensions of the cell (do this each time because the user may have resized this column)
_cboColumn.Bounds = bounds;
// do not paint the control until we've set the correct position in the items list
_cboColumn.BeginUpdate();
// note: on the very first time this routine is called you MUST set the column as visible
// ahead of setting a position in the items collection. otherwise the combobox will not be
// populated and the call to set the SelectedValue cannot succeed
//if there is no this value in this combobox,Don't display the combobox
DataRow[] aRowA;
aRowA=((DataTable)_objSource).Select(_strValue + " = " + anObj);
if(aRowA.Length>0)
{
_cboColumn.Visible = true;
}
// use the object to set the combobox. the null detection is primarily aimed at the addition of a
// new row (where it is possible a default column-row content has not been defined)
if (anObj.GetType() != typeof(System.DBNull))
{
_cboColumn.SelectedValue = anObj;
}
else
{
_cboColumn.SelectedIndex = 0;
}
// we've set the combobox so we can now paint the control and move focus onto it
_cboColumn.EndUpdate();
_cboColumn.Focus();
// below is the default method which we definitely DONT want to call as the text box must remain dormant!
// base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible);
//做呈现用,禁止编辑
_cboColumn.Visible=false;
} public void cboColumn_Leave(object sender, EventArgs e)
{
// We are going to write back the ValueMember from combobox into the current column-row in the
// table displayed by the DataGrid control. Finally we hide the combobox. note the source and
// row were saved when the edit began - see Edit()
object objValue = _cboColumn.SelectedValue;
// we can write System.DBNull back to a database but we cannot write null (which would
// cause an exception). if the combobox is defined as a dropdownlist we cannot see the
// null value. However if the combobox is defined as a dropdown then editing into the
// combobox will, by default, generate a null value. For this possibility we translate
// null to the System.DBNull value if (objValue == null)
{
objValue = DBNull.Value;
}
this.SetColumnValueAtRow(_cmSource, _iRowNum, objValue);
_cboColumn.Visible = false;
}
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight)
{
// there are three Paint() methods that can be overriden. I put break points in all three, but this
// was the only one I caught. If you find odd paint behaviors please let me know and I'll investigate
string strCountry;
DataRow[] aRowA; // retrieve the value at the current column-row within the source for this column
object anObj = this.GetColumnValueAtRow(source, rowNum);
// use this value to access the datasource. again, we must allow that a null object
// is returned; this typically only happens when adding a new row to the DataGrid host
Type aType = anObj.GetType();
if (aType != typeof(System.DBNull))
{
if(aType==typeof(System.String))
{
aRowA = ((DataTable)_objSource).Select(_strValue + "='" + anObj+"'");
}
else
{
aRowA = ((DataTable)_objSource).Select(_strValue + "=" + anObj);
}
if(aRowA.Length<=0)
{
strCountry="-无-";
}
else
{
strCountry = aRowA[0][_strMember].ToString();
}
}
else
{
strCountry=this.NullText;
}
//if (aRowA.Length > 0)
//{
// strCountry = aRowA[0][_strMember].ToString();
//}
// all we are going to do is repaint the cell. Empiric observation indicates this code is ONLY
// called when the column is not in edit mode, however you could wrap conditional code around
// this to block an unwanted paint event calling during an edit operation
Rectangle rect = bounds;
// use custom background color if the property was set by the User
if (this._backBrush == null)
g.FillRectangle(backBrush, rect);
else
g.FillRectangle(_backBrush, rect);
// vertical offset to account for frame of combobox
rect.Y += 2;
if (this._foreBrush == null)
g.DrawString(strCountry, this.TextBox.Font, foreBrush, rect);
else
g.DrawString(strCountry, this.TextBox.Font, _foreBrush, rect);
} public System.Drawing.Color backgroundColour
{
set { if (value == System.Drawing.Color.Transparent) this._backBrush = null; else this._backBrush = new SolidBrush(value); }
} public System.Drawing.Color foregroundColour
{
set { if (value == System.Drawing.Color.Transparent) this._foreBrush = null; else this._foreBrush = new SolidBrush(value); }
} // below are the two other Paint() and the other Edit() override. if you re-enable the code and set a
// breakpoint in each, you can test to see if either method gets called!
/*
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum)
{
base.Paint(g, bounds, source, rowNum);
} protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight)
{
base.Paint(g, bounds, source, rowNum, alignToRight);
}
protected override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly)
{
base.Edit (source, rowNum, bounds, readOnly);
}
*/ private void TextBox_MouseMove(object sender, MouseEventArgs e)
{
//this.TextBox.Focus();
}
}
}
但是,我现在有一个窗体和datagrid是关联起来的,我修改了上面的字段,比如:把“完成”改为“未完成”了,我现在又怎么修改数据库,而且还要试datagrid里显示“未完成”
===============================================================================
添加一个模板列,之后里面放一个dropdownlist 添加上0:完成 1:未完成
保存的时候根据dropdownlist 选择的值进行存储
你把datagrid的sql语句写成如下格式
string str_sql = "select a = case when a=0 then '未完成' else '已完成' end from 数据表"
a 是datagrid绑定列的数据字段,针对多情况 case when 可以多次使用,但最后必须跟end。
private void DataBindings_CollectionChanged(object sender, CollectionChangeEventArgs e)
{
try
{
dataType=null;
if (bd!=null)
{
bd.Parse -= new ConvertEventHandler(bd_Parse);
bd.Format -= new ConvertEventHandler(bd_Format);
}
bd= DataBindings["Checked"];
if (bd!=null)
{
bd.Parse += new ConvertEventHandler(bd_Parse);
bd.Format += new ConvertEventHandler(bd_Format);
if (bd.BindingManagerBase !=null)
dataType=bd.BindingManagerBase.GetItemProperties()[bd.BindingMemberInfo.BindingField ].PropertyType;
}
}
catch{throw;}}[
Category("格式"),
Editor(typeof(upTypeSelectEditor), typeof(UITypeEditor)),
DefaultValue(typeof (System.String)),
Description("被绑定到的数据类型")
]
public Type DataType
{
get{return dataType;}
}private void bd_Format(object sender, ConvertEventArgs e)
{
try
{
if (e.Value==System.DBNull.Value || e.Value ==null)
{
this.CheckState =CheckState.Indeterminate ;
e.Value =false;
return;
}
string typeName=e.Value.GetType ().Name ;
if (upSysFunc.InList (typeName,"Decimal","Double","Single","Int16","Int32","Int64")>=0)
e.Value =((int)e.Value )!=0;
else if (upSysFunc.InList (typeName,"UInt16","UInt32","UInt64")>=0)
e.Value =((int)e.Value )!=0;
else if (typeName=="String" && upSysFunc.InList(e.Value.ToString ().ToUpper (),"YES","NO","TRUE","FALSE","真","假","是","否")>=0)
e.Value =bool.Parse (e.Value.ToString () );
else if (typeName =="Boolean")
e.Value =e.Value ;
else
throw new Exception ("不能绑定的数据类型:" + typeName ) ; }
catch (System.Exception ex )
{upApp.HaveErr((Control)sender,new Exception ( "数据类型不合格\n" ,ex),1); }
} private void bd_Parse(object sender, ConvertEventArgs e)
{
try
{
if (!bd.IsBinding ) return ;