Zendy

---勿在浮沙筑高台---

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 在一个项目中,我遇到这样一个问题: 数据库字段只存储了一个字典ID1,在DataGrid中显示时,需要用相应的字典Value1来代替字典ID1显示.解决这个问题一般有两个方法:
方法1:  数据库查询Sql脚本直接把相应的字典Value1值查询出来.
方法2: 在显示DataGrid时,把相应的字典ID1转换成字典Value1显示.

关于方法1, 实现相对简单但是不灵活,并且我们采用的是强类型的DataSet,不想经常修改强类型Dataset的定义
关于方法2, 实现上相对复杂一些但是比较灵活,也不用破坏已定义的强类型DataSet.

于是我就决定采用方法二,上网也找了不少资料,终于在codeproejct找到一篇比较符合我需求的文章,我的实现逻辑如下:在创建Datagrid的column时,对于需要替换的column:Dict1用自定义的LookUpColumn来代替, 设置LookupColumn的Datasource DispalyMember及ValueMember,当Dataset中相应字段的值与LookupColumn的Datasource的ValueMember值相匹配时,显示相应的DispalyMember值.具体代码如下:

   DataGridLookupColumn lcolumnex = new DataGridLookupColumn(); 
   lcolumnex.MappingName 
= "Dict1"
   lcolumnex.HeaderText 
= lcolumnex.MappingName;   
   lcolumnex.comboBox.ValueMember 
= "DictID"
   lcolumnex.comboBox.DisplayMember 
= "DictValue"
   lcolumnex.Width 
= 80
   lcolumnex.comboBox.DataSource 
= CommonValue.GetDictList();//返回Dict结构(有DictID,DictValue属性)组成的一个ArrayList 
   lTableStyle.GridColumnStyles.Add(lcolumnex); 



具体的DataGridLookupColumn类实现代码如下:

/*本代码原稿由http://www.codeproject.com/cs/miscctrl/RenDataGridComboBoxColumn.asp获取,并做了相应的改动 by Zendyhu
*/

#region DataGridLookupColumn
    
//**********************************************************************************************
    
//    DataGridLookupColumn
    
//**********************************************************************************************
    public class DataGridLookupColumn : DataGridColumnStyle 
    
//DataGridLookupColumn {
        private    DataGridComboBox    combobox;
        
private    bool                    edit;

        
//-------------------------------------------------------------------------------------------
        
//    Constructors and destructors
        
//-------------------------------------------------------------------------------------------
        public DataGridLookupColumn() 
        
{
            combobox                                        
= new DataGridComboBox();
            combobox.Visible                            
= false;
            combobox.DropDownStyle                    
= ComboBoxStyle.DropDownList;
            combobox.Leave                                
+= new EventHandler(ComboHide);
            combobox.SelectionChangeCommitted    
+= new EventHandler(ComboStartEditing);
            edit                                            
= false;
        }
 // DataGridLookupColumn

        
//-------------------------------------------------------------------------------------------
        
//    Properties
        
//-------------------------------------------------------------------------------------------
        public ComboBox comboBox 
        
{
            
get 
            
{
                
return combobox;
            }

        }
 // comboBox

        
//-------------------------------------------------------------------------------------------
        
//    ComboBox event handlers
        
//-------------------------------------------------------------------------------------------
        private void ComboHide(object sender, EventArgs e) 
        
{
            
// When the ComboBox looses focus, then simply hide it.
            combobox.Hide();
        }
 // ComboHide

        
private void ComboStartEditing(object sender, EventArgs e) 
        
{
            
// Enter edit mode.
            edit = true;
            
base.ColumnStartedEditing((Control)sender);
        }
 // ComboStartEditing

        
//-------------------------------------------------------------------------------------------
        
//    Override DataGridColumnStyle
        
//-------------------------------------------------------------------------------------------
        protected override void SetDataGridInColumn(DataGrid value) 
        
{
            
// Add the ComboBox to the DataGrids controls collection.
            
// This ensures correct DataGrid scrolling.
            value.Controls.Add(combobox);
            
base.SetDataGridInColumn(value);
        }
 // SetDataGridInColumn

        
protected override void Abort(int rowNum) 
        
{
            
// Abort edit mode, discard changes and hide the ComboBox.
            edit = false;
            Invalidate();
            combobox.Hide();
        }
 // Abort

        
protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible) 
        
{
            
// Setup the ComboBox for action.
            
// This includes positioning the ComboBox and showing it.
            
// Also select the correct item in the ComboBox before it is shown.
            combobox.Parent            = this.DataGridTableStyle.DataGrid;
            combobox.Bounds            
= bounds;
            combobox.Size                
= new Size(this.Width, this.comboBox.Height);
            comboBox.SelectedValue    
= base.GetColumnValueAtRow(source, rowNum).ToString();
            combobox.Visible            
= (cellIsVisible == true&& (readOnly == false);
            combobox.BringToFront();
            combobox.Focus();    
        }
 // Edit

        
protected override bool Commit(System.Windows.Forms.CurrencyManager source, int rowNum) 
        
{
            
// Commit the selected value from the ComboBox to the DataGrid.
            if (edit == true
            
{
                edit 
= false;
                
this.SetColumnValueAtRow(source, rowNum, combobox.SelectedValue);
            }


            
return true;
        }
 // Commit

        
protected override object GetColumnValueAtRow(System.Windows.Forms.CurrencyManager source, int rowNum) 
        
{
            
// Return the display text associated with the data, insted of the
            
// data from the DataGrid datasource.
            return combobox.GetDisplayText(base.GetColumnValueAtRow(source, rowNum));
        }
 // GetColumnValueAtRow

        
protected override void SetColumnValueAtRow(CurrencyManager source, int rowNum, object value) 
        
{
            
// Save the data (value) to the DataGrid datasource.
            
// I try a few different types, because I often uses GUIDs as keys in my
            
// data.

            
// String.
            try 
            
{
                
base.SetColumnValueAtRow(source, rowNum, value.ToString());
                
return;
            }
 
            
catch {}

            
// Guid.
            try 
            
{
                
base.SetColumnValueAtRow(source, rowNum, new Guid(value.ToString()));
                
return;
            }
 
            
catch {}

            
// Object (default).
            base.SetColumnValueAtRow(source, rowNum, value);
        }
 // SetColumnValueAtRow

        
protected override int GetMinimumHeight() 
        
{
            
// Return the ComboBox preferred height, plus a few pixels.
            return combobox.PreferredHeight;
        }
 // GetMinimumHeight
        
        
protected override int GetPreferredHeight(Graphics g, object val) 
        
{
            
// Return the font height, plus a few pixels.
            return FontHeight + 2;
        }
 // GetPreferredHeight

        
protected override Size GetPreferredSize(Graphics g, object val) 
        
{
            
// Return the preferred width.
            
// Iterate through all display texts in the dropdown, and measure each
            
// text width.
            int        widest        = 0;
            SizeF        stringSize    
= new SizeF(00);
            
foreach (string text in combobox.GetDisplayText()) 
            
{
                stringSize    
= g.MeasureString(text, base.DataGridTableStyle.DataGrid.Font);
                
if (stringSize.Width > widest) 
                
{
                    widest 
= (int)Math.Ceiling(stringSize.Width);
                }

            }


            
return new Size(widest + 25, combobox.PreferredHeight + 2);
        }
 // GetPreferredSize

        
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum) 
        
{
            Paint(g, bounds, source, rowNum, 
false);
        }
 // Paint

        
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight) 
        
{
            
string            text                = GetColumnValueAtRow(source, rowNum).ToString();
            Brush                backBrush        
= new SolidBrush(base.DataGridTableStyle.BackColor);
            Brush                foreBrush        
= new SolidBrush(base.DataGridTableStyle.ForeColor);
            Rectangle        rect                
= bounds;
            StringFormat    format            
= new StringFormat();

            
// Handle that the row can be selected.
            if (base.DataGridTableStyle.DataGrid.IsSelected(rowNum) == true
            
{
                backBrush        
= new SolidBrush(base.DataGridTableStyle.SelectionBackColor);
                foreBrush        
= new SolidBrush(base.DataGridTableStyle.SelectionForeColor);
            }


            
// Handle align to right.
            if (alignToRight == true
            
{
                format.FormatFlags    
= StringFormatFlags.DirectionRightToLeft;
            }


            
// Handle alignment.
            switch (this.Alignment) 
            
{
                
case HorizontalAlignment.Left:
                    format.Alignment    
= StringAlignment.Near;
                    
break;
                
case HorizontalAlignment.Right:
                    format.Alignment    
= StringAlignment.Far;
                    
break;
                
case HorizontalAlignment.Center:
                    format.Alignment    
= StringAlignment.Center;
                    
break;
            }


            
// Paint.
            format.FormatFlags        = StringFormatFlags.NoWrap;
            g.FillRectangle(backBrush, rect);
            rect.Offset(
02);
            rect.Height 
-= 2;
            g.DrawString(text, 
this.DataGridTableStyle.DataGrid.Font, foreBrush, rect, format);
            format.Dispose();
        }
 // PaintText

    }
 // DataGridLookupColumn
    #endregion


    
#region DataGridComboBox
    
//**********************************************************************************************
    
//    DataGridComboBox
    
//**********************************************************************************************
    public class DataGridComboBox : ComboBox 
    
{
        
private const int WM_KEYUP = 0x101;

        
protected override void WndProc(ref System.Windows.Forms.Message message) 
        
{
            
// Ignore keyup to avoid problem with tabbing and dropdown list.
            if (message.Msg == WM_KEYUP) 
            
{
                
return;
            }


            
base.WndProc(ref message);
        }
 // WndProc

        
public string GetValueText(int index) 
        
{
            
// Validate the index.
            if ((index < 0&& (index >= base.Items.Count))
                
throw new IndexOutOfRangeException("Invalid index.");

            
// Get the text.
            string    text            = string.Empty;
            
int        memIndex        = -1;
            
try 
            
{
                
base.BeginUpdate();
                memIndex                    
= base.SelectedIndex;
                
base.SelectedIndex    = index;
                text                        
= base.SelectedValue.ToString();
                
base.SelectedIndex    = memIndex;
            }
 
            
catch 
            
{
            }
 
            
finally 
            
{
                
base.EndUpdate();
            }


            
return text;
        }
 // GetValueText

        
public string GetDisplayText(int index) 
        
{
            
// Validate the index.
            if ((index < 0&& (index >= base.Items.Count))
                
throw new IndexOutOfRangeException("Invalid index.");

            
// Get the text.
            string    text            = string.Empty;
            
int        memIndex        = -1;
            
try 
            
{
                
base.BeginUpdate();
                memIndex                    
= base.SelectedIndex;
                
base.SelectedIndex    = index;
                text                        
= base.SelectedItem.ToString();
                
base.SelectedIndex    = memIndex;
            }
 
            
catch 
            
{
            }
 
            
finally 
            
{
                
base.EndUpdate();
            }


            
return text;
        }
 // GetDisplayText

        
public string GetDisplayText(object value) 
        
{    //mdified by zendyhu 2004-12  to fixed bug when the getValueByID
            string text1 = this.ValueMember;
            
if (text1.Equals(string.Empty))
                
return "";

            
if (DataSource == null)
                
return "";
            
if (!(DataSource is IList))
            
{
                
return "";
            }


            
foreach(object obj in (IList)DataSource)
            
{
                
object obj2 = FilterItemOnProperty(obj,text1);

                
if(value.ToString().Trim().ToUpper() == obj2.ToString().Trim().ToUpper())
                
{
                    
return GetItemText(obj);
                }

            }

            
return "";
            
// Get the text.
//            string    text            = string.Empty;
//            int        memIndex        = -1;
//            try 
//            {                
//                base.BeginUpdate();
//                memIndex                    = base.SelectedIndex;
//                base.SelectedValue    = value;
//                text                        = base.Text.ToString();
//                base.SelectedIndex    = memIndex;
//            } 
//            catch 
//            {
//            } 
//            finally 
//            {
//                base.EndUpdate();
//            }
//
//            return text;
        }
 // GetDisplayText

        
public string[] GetDisplayText() 
        
{
            
// Get the text.
            string[]    text            = new string[base.Items.Count];
            
int        memIndex        = -1;
            
try 
            
{
                
base.BeginUpdate();
                memIndex                    
= base.SelectedIndex;
                
for (int index = 0; index < base.Items.Count; index++
                
{
                    
base.SelectedIndex    = index;
                    text[index]                
= base.SelectedItem.ToString();
                }

                
base.SelectedIndex    = memIndex;
            }
 
            
catch 
            
{
            }
 
            
finally 
            
{
                
base.EndUpdate();
            }


            
return text;
        }
 // GetDisplayText

    }
 // DataGridComboBox
    #endregion



posted on 2005-04-23 16:39  Zendy  阅读(1605)  评论(1)    收藏  举报