ManageGrid

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;

namespace SouEi.WebManagePager
{
 #region PagingMode enum
 public enum PagingMode
 {
  Cached,
  NonCached
 }
 #endregion
 
 #region PagerStyle enum
 public enum myPagerStyle
 {
  NextPrev,
  NumericPages
 }
 #endregion

 #region PageChangedEventArgs class
 public class PageChangedEventArgs : EventArgs
 {
  public int OldPageIndex;
  public int NewPageIndex;
 }
 #endregion
 /// <summary>
 /// Summary description for DataGrid.
 /// </summary>
 [DefaultProperty("Text"),
 ToolboxData("<{0}:ManageGrid runat=server></{0}:ManageGrid>")]
 [DefaultEvent("PageIndexChanged")]
 public class ManageGrid : System.Web.UI.WebControls.DataGrid
 {
  private string CurrentPageText = "ラワシヌツシ:<font color=#ff0000><B>{2}</B></font>&nbsp&nbspメウエホ:<font color=#ff0000><B>{0}</B></font>/<B>{1}</B>メウ&nbsp&nbsp<B>{3}</B>/メウ";
  private string NoPageSelectedText = "";
  private PagedDataSource _dataSource;
  private string CacheKeyName
  {
   get {return Page.Request.FilePath + "_" + UniqueID + "_Data";}
  }
  private string text;
  private SqlDataAdapter adp;
  private DataSet ds = new DataSet();
  private DataView view;
  private string[] arritem;
  [Bindable(true),
  Category("Appearance"),
  DefaultValue("")]
  public string Text
  {
   get
   {
    return text;
   }

   set
   {
    text = value;
   }
  }
  /// <summary>
  /// protect SortDirection
  /// </summary>

  public string SortDirection
  {
   get
   {
    if(ViewState["SortDirection"]==null)
    {
     return null;
    }
    else
    {
     if(ViewState["SortDirection"].ToString()=="")
     {
      return null;
     }
     else
     {
      return ViewState["SortDirection"].ToString();
     }
    }
   }
   set
   {
    ViewState["SortDirection"]=value;
   }
  }
//  /// <summary>
//  /// protect SortField
//  /// </summary>
//  public string SortField
//  {
//   get
//   {
//    if(ViewState["SortField"]==null)
//    {
//     return null;
//    }
//    else
//    {
//     if(ViewState["SortField"].ToString()=="")
//     {
//      return null;
//     }
//     else
//     {
//      return ViewState["SortField"].ToString();
//     }
//    }
//   }
//   set
//   {
//    ViewState["SortField"]=value;
//   }
//  }
  /// <summary>
  /// sqlCommandText
  /// </summary>       
//  public string SelectCommand
//  {
//   get
//   {
//    if(ViewState["SelectCommand"]==null)
//    {
//     return null;
//    }
//    else
//    {
//     if(ViewState["SelectCommand"].ToString()=="")
//     {
//      return null;
//     }
//     else
//     {
//
//      return ViewState["SelectCommand"].ToString();
//     }
//    }
//   }
//   set
//   {
//    ViewState["SelectCommand"]=value;
//   }
//  }
//  /// <summary>
//  /// ConnectionString
//  /// </summary>
//  public string ConnectionString
//  {
//   get
//   {
//    if(ViewState["ConnectionString"]==null)
//    {
//     return null;
//    }
//    else
//    {
//     return ViewState["ConnectionString"].ToString();
//    }
//   }
//   set
//   {
//    ViewState["ConnectionString"]=value;
//   }
//  }
  public DataTable Bindtable;
  public ManageGrid():base()
  {
   _dataSource = null;

   PagingMode = PagingMode.Cached;
   myPagerStyle = myPagerStyle.NextPrev;
   CurrentPageIndex = 0;
   SelectCommand = "";
   ConnectionString = "";
   ItemsPerPage = 10;
   TotalPages = -1;
   TotalRecord = -1;
   CacheDuration = 60;
   this.Init+=new System.EventHandler(this.DataGrid_Init);
  }
  private void DataGrid_Init(object sender,EventArgs e)
  {

   this.Load+= new System.EventHandler(this.DataGrid_Load);           
   this.SortCommand+=new System.Web.UI.WebControls.DataGridSortCommandEventHandler(this.DataGrid_SortCommand);
   this.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.DataGrid_ItemDataBound);

  }
  private void DataGrid_Load(object sender,EventArgs e)
  {
   this.HorizontalAlign=HorizontalAlign.Center;
   this.AllowSorting=true;
   arritem=new string[256];
   ds=new DataSet();
   //CreateChildControls();
           
           
  }
    

  /// <summary>
  /// GRIDBinding
  /// </summary>
  /// <param name="SelectCommand">sql</param>
  /// <param name="ConnectionString">constr</param>
  public void BindGrid(string SelectCommand,string ConnectionString)
  {
   this.SelectCommand=SelectCommand;
   this.ConnectionString=ConnectionString;
   BindGrid();
            
  }
  /// <summary>
  /// gridbind
  /// </summary>
  /// <param name="SelectCommand">sql</param>
  /// <param name="cn">cn</param>
  public void BindGrid(string SelectCommand,SqlConnection cn)
  {
   this.SelectCommand=SelectCommand;
   this.ConnectionString=cn.ConnectionString;
   BindGrid();
  }
  /// <summary>
  /// grid
  /// </summary>
  public void BindGrid()
  {
   // Fires the data binding event
   base.DataBind();

   // Controls must be recreated after data binding
   ChildControlsCreated = false;

   // Ensures enough info to connect and query is specified
   if (ConnectionString == "" || SelectCommand == "")
    return;

   // Fetch data
   if (PagingMode == PagingMode.Cached)
    FetchAllData();
   else
   {
    //if (SortField == "")
    // return;
    //FetchPageData();
   }

   // Bind data to the buddy control
   this.DataSource = _dataSource;
   this.DataBind();
   //baseDataListControl.DataBind();

   return;
//   if(this.SelectCommand!=null&&this.ConnectionString!=null)
//   {
//    adp=new SqlDataAdapter(this.SelectCommand,this.ConnectionString);
//    adp.Fill(ds,"temp");
//    view=ds.Tables["temp"].DefaultView;
//
//    if(this.SortField!=null)
//    {
//     view.Sort=this.SortField+" "+this.SortDirection;
//     int sortfieldindex=0;
//     for( int  i=0;i<ds.Tables["temp"].Columns.Count;i++)
//     {
//      if(ds.Tables["temp"].Columns[i].ColumnName==this.SortField)
//      {
//       sortfieldindex=i;
//       break;
//      }
//     }
//     string SortDirectionImg="▲";
//     if(this.SortDirection==" DESC")
//     {
//      SortDirectionImg="▼";
//
//     }
//     if(this.SortField!=this.DataKeyField)
//     {
//      ds.Tables["temp"].Columns[sortfieldindex].ColumnName+=SortDirectionImg;
//     }
//                   
//    }
//    Bindtable=ds.Tables["temp"];
//    DataRow row=Bindtable.NewRow();
//    row[0]="Sum:";               
//    for(int i=1;i<Bindtable.Columns.Count;i++)
//    {   
//     Type t=Bindtable.Columns[i].DataType;
//     if(t==typeof(Decimal)||t==typeof(Double)||t==typeof(Int16)||t==typeof(Int32)||t==typeof(Int64)||t==typeof(UInt16)||t==typeof(UInt32)||t==typeof(Int64))
//     {
//      row[i]=0;
//      foreach( DataRow r in Bindtable.Rows)
//      {
//       try
//       {
//        row[i]=double.Parse(row[i].ToString())+double.Parse(r[i].ToString());
//       }
//       catch(Exception et)
//       {
//                            
//       }
//                           
//      }
//     }
//    }
//    Bindtable.Rows.Add(row);
//               
//    this.DataSource=view;
//    this.DataBind();
//               
//   }
//   else
//   {
//               
//   }
  }
  // ***********************************************************************
  // PRIVATE ValidatePageIndex
  // Ensures the CurrentPageIndex is either valid [0,TotalPages) or -1
  private void ValidatePageIndex()
  {
   if (!(CurrentPageIndex >=0 && CurrentPageIndex < TotalPages))
    CurrentPageIndex = -1;
   return;
  }
  // ***********************************************************************
  // ***********************************************************************
  // PRIVATE FetchAllData
  // Runs the query for all data to be paged and caches the resulting data
  private void FetchAllData()
  {
   // Looks for data in the ASP.NET Cache
   DataTable data;
   data = (DataTable) Page.Cache[CacheKeyName];
    
   if (data == null)
   {
    // Fix SelectCommand with order-by info
    AdjustSelectCommand(true);

    // If data expired or has never been fetched, go to the database
    SqlDataAdapter adapter = new SqlDataAdapter(SelectCommand, ConnectionString);
    data = new DataTable();
    adapter.Fill(data);
    Page.Cache.Insert(CacheKeyName, data, null,
     DateTime.Now.AddSeconds(CacheDuration),
     System.Web.Caching.Cache.NoSlidingExpiration);
   }
  
   // Configures the paged data source component
   if (_dataSource == null)
    _dataSource = new PagedDataSource();
   _dataSource.DataSource = data.DefaultView; // must be IEnumerable!
   _dataSource.AllowPaging = true;
   _dataSource.PageSize = ItemsPerPage;
   TotalPages = _dataSource.PageCount;
   TotalRecord = data.Rows.Count;
   // Ensures the page index is valid
   ValidatePageIndex();
   if (CurrentPageIndex == -1)
   {
    _dataSource = null;
    return;
   }

   // Selects the page to view
   _dataSource.CurrentPageIndex = CurrentPageIndex;
  }
  // ***********************************************************************

  // ***********************************************************************
  // PRIVATE AdjustSelectCommand
  // Strips ORDER-BY clauses from SelectCommand and adds a new one based
  // on SortKeyField
  private void AdjustSelectCommand(bool addCustomSortInfo)
  {
   // Truncate where ORDER BY is found
   string temp = SelectCommand.ToLower();
   int pos = temp.IndexOf("order by");
   if (pos > -1)
    SelectCommand = SelectCommand.Substring(0, pos);

   // Add new ORDER BY info if SortKeyField is specified
   if (SortField != "" && addCustomSortInfo)
    SelectCommand += " ORDER BY " + SortField;
  }
  // ***********************************************************************

  private void DataGrid_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
  {
           
   if(    this.SortDirection==" DESC")
   {
    this.SortDirection=" ASC";
   }
   else
   {
    this.SortDirection=" DESC";
   }
           
   this.SortField=e.SortExpression;
   this.SortField=this.SortField.Replace("▲","");
   this.SortField=this.SortField.Replace("▼","");
           
   BindGrid();
  }


  private void DataGrid_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
  {
   try
   {
    string txt="";
    for(int i=0;i<e.Item.Cells.Count;i++)
    {
     //                    e.Item.Cells[i].Wrap=false;
     txt=e.Item.Cells[i].Text.Trim();
   
     //     if(myClass.IsDouble(txt))
     //     {
     //      e.Item.Cells[i].HorizontalAlign=HorizontalAlign.Right;
     //     }
     //     else
     //     {
     if(txt==arritem[i]&&txt!=""&&txt!=null)
     {
      e.Item.Cells[i].Text="";
     }
     else
     {
      arritem[i]=txt;
     }
     //     }
    }
   }
   catch
   {
               
   }

  }
  #region PUBLIC PROGRAMMING INTERFACE
  // ***********************************************************************
  // METHOD ClearCache
  // Removes any data cached for paging
  public void ClearCache()
  {
   if (PagingMode == PagingMode.Cached)
    Page.Cache.Remove(CacheKeyName);
  }
  // ***********************************************************************

  // ***********************************************************************
  // EVENT PageIndexChanged
  // Fires when the pager is about to switch to a new page
  public delegate void PageChangedEventHandler(object sender, PageChangedEventArgs e);
  public event PageChangedEventHandler myPageIndexChanged;
  protected virtual void OnPageIndexChanged(PageChangedEventArgs e)
  {
   if (myPageIndexChanged != null)
    myPageIndexChanged(this, e);
  }
  // ***********************************************************************

  // ***********************************************************************
  // PROPERTY CacheDuration
  [Description("Gets and sets for how many seconds the data should stay in the cache")]
  public int CacheDuration
  {
   get {return Convert.ToInt32(ViewState["CacheDuration"]);}
   set {ViewState["CacheDuration"] = value;}
  }
  // ***********************************************************************

  // ***********************************************************************
  // PROPERTY PagingMode
  [Description("Indicates whether the data are retrieved page by page or can be cached")]
  public PagingMode PagingMode
  {
   get {return (PagingMode) ViewState["PagingMode"];}
   set {ViewState["PagingMode"] = value;}
  }
  // ***********************************************************************

  // ***********************************************************************
  // PROPERTY PagerStyle
  [Description("Indicates the style of the pager's navigation bar")]
  public myPagerStyle myPagerStyle
  {
   get {return (myPagerStyle) ViewState["myPagerStyle"];}
   set {ViewState["myPagerStyle"] = value;}
  }
  // ***********************************************************************  

  // ***********************************************************************
  // PROPERTY ItemsPerPage
  [Description("Gets and sets the number of items to display per page")]
  public int ItemsPerPage
  {
   get {return Convert.ToInt32(ViewState["ItemsPerPage"]);}
   set {ViewState["ItemsPerPage"] = value;}
  }
  // ***********************************************************************

  // ***********************************************************************
  // PROPERTY CurrentPageIndex
  [Description("Gets and sets the index of the currently displayed page")]
  public int myCurrentPageIndex
  {
   get {return Convert.ToInt32(ViewState["CurrentPageIndex"]);}
   set {ViewState["CurrentPageIndex"] = value;}
  }
  // ***********************************************************************

  // ***********************************************************************
  // PROPERTY ConnectionString
  [Description("Gets and sets the connection string to access the database")]
  public string ConnectionString
  {
   get {return Convert.ToString(ViewState["ConnectionString"]);}
   set {ViewState["ConnectionString"] = value;}
  }
  // ***********************************************************************

  // ***********************************************************************
  // PROPERTY SelectCommand
  [Description("Gets and sets the SQL query to get data")]
  public string SelectCommand
  {
   get {return Convert.ToString(ViewState["SelectCommand"]);}
   set {ViewState["SelectCommand"] = value;}
  }
  // ***********************************************************************

  // ***********************************************************************
  // PROPERTY SortField
  [Description("Gets and sets the sort-by field. It is mandatory in NonCached mode.)")]
  public string SortField
  {
   get {return Convert.ToString(ViewState["SortKeyField"]);}
   set {ViewState["SortKeyField"] = value;}
  }
  // ***********************************************************************

  // ***********************************************************************
  // PROPERTY PageCount
  // Gets the number of displayable pages
  [Browsable(false)]
  public int myPageCount
  {
   get {return TotalPages;}
  }
  // ***********************************************************************

  // ***********************************************************************
  // PROPERTY TotalPages
  // Gets and sets the number of pages to display
  protected int TotalPages
  {
   get {return Convert.ToInt32(ViewState["TotalPages"]);}
   set {ViewState["TotalPages"] = value;}
  }
  // ***********************************************************************

  // ***********************************************************************
  // PROPERTY TotalPages
  // Gets and sets the number of pages to display
  protected int TotalRecord
  {
   get {return Convert.ToInt32(ViewState["TotalRecord"]);}
   set {ViewState["TotalRecord"] = value;}
  }
  // ***********************************************************************

//  // ***********************************************************************
//  // OVERRIDE DataBind
//  // Fetches and stores the data
//  public override void DataBind()
//  {
//   // Fires the data binding event
//   base.DataBind();
//
//   // Controls must be recreated after data binding
//   ChildControlsCreated = false;
//
//   // Ensures enough info to connect and query is specified
//   if (ConnectionString == "" || SelectCommand == "")
//    return;
//
//   // Fetch data
//   if (PagingMode == PagingMode.Cached)
//    FetchAllData();
//   else
//   {
//    //if (SortField == "")
//    // return;
//    //FetchPageData();
//   }
//
//   // Bind data to the buddy control
//   BaseDataList baseDataListControl = null;
//   baseDataListControl = (BaseDataList) this;
//   baseDataListControl.DataSource = _dataSource;
//   baseDataListControl.DataBind();
//  }
//  // ***********************************************************************

  // ***********************************************************************
  // OVERRIDE Render
  // Writes the content to be rendered on the client
  protected override void Render(HtmlTextWriter output)
  {
   // If in design-mode ensure that child controls have been created.
   // Child controls are not created at this time in design-mode because
   // there's no pre-render stage. Do so for composite controls like this
   if (Site != null && Site.DesignMode)
    CreateChildControls();

   base.Render(output);
  }
  // ***********************************************************************

  // ***********************************************************************
  // OVERRIDE CreateChildControls
  // Outputs the HTML markup for the control
  protected override void CreateChildControls()
  {
   //Controls.Clear();
   ClearChildViewState();

   BuildControlHierarchy();
  }
  // ***********************************************************************
  #endregion

  #region PRIVATE HELPER METHODS
  // ***********************************************************************
  // PRIVATE BuildControlHierarchy
  // Control the building of the control's hierarchy
  private void BuildControlHierarchy()
  {
   // Build the surrounding table (one row, two cells)
   Table t = new Table();
   t.Width = new Unit("100%");
   // Build the table row
   TableRow row = new TableRow();
   t.Rows.Add(row);

   // Build the cell with the page index
   TableCell cellPageDesc = new TableCell();
   cellPageDesc.HorizontalAlign = HorizontalAlign.Left;
   BuildCurrentPage(cellPageDesc);
   row.Cells.Add(cellPageDesc);

   // Build the cell with navigation bar
   TableCell cellNavBar = new TableCell();
   if (myPagerStyle == myPagerStyle.NextPrev)
    BuildNextPrevUI(cellNavBar);
   else
    BuildNumericPagesUI(cellNavBar);
   cellNavBar.HorizontalAlign = HorizontalAlign.Right;
   row.Cells.Add(cellNavBar);

   // Add the table to the control tree
   Controls.Add(t);
  }
  // ***********************************************************************
  #endregion

  // ***********************************************************************
  // PRIVATE BuildCurrentPage
  // Generates the HTML markup to describe the current page (0-based)
  private void BuildCurrentPage(TableCell cell)
  {
   // Use a standard template: Page X of Y
   if (CurrentPageIndex <0 || CurrentPageIndex >= TotalPages)
    cell.Text = NoPageSelectedText;
   else
    cell.Text = String.Format(CurrentPageText, (CurrentPageIndex+1), TotalPages, TotalRecord, ItemsPerPage);
  }
  // ***********************************************************************

  // ***********************************************************************
  // PRIVATE BuildNextPrevUI
  // Generates the HTML markup for the Next/Prev navigation bar
  private void BuildNextPrevUI(TableCell cell)
  {
   bool isValidPage = (CurrentPageIndex >=0 && CurrentPageIndex <= TotalPages-1);
   bool canMoveBack = (CurrentPageIndex>0);
   bool canMoveForward = (CurrentPageIndex<TotalPages-1);

   // Render the << button
   LinkButton first = new LinkButton();
   first.ID = "First";
   first.CausesValidation = false;
   first.Click += new EventHandler(first_Click);
   first.Text = " ハラメウ "; 
   first.Enabled = isValidPage && canMoveBack;
   cell.Controls.Add(first);

   // Add a separator
   cell.Controls.Add(new LiteralControl("&nbsp;"));

   // Render the < button
   LinkButton prev = new LinkButton();
   prev.ID = "Prev";
   prev.CausesValidation = false;
   prev.Click += new EventHandler(prev_Click);
   prev.Text = " ノマメウ "; 
   prev.Enabled = isValidPage && canMoveBack;
   cell.Controls.Add(prev);

   // Add a separator
   cell.Controls.Add(new LiteralControl("&nbsp;"));

   // Render the > button
   LinkButton next = new LinkButton();
   next.ID = "Next";
   next.CausesValidation = false;
   next.Click += new EventHandler(next_Click);
   next.Text = " マツメウ "; 
   next.Enabled = isValidPage && canMoveForward;
   cell.Controls.Add(next);

   // Add a separator
   cell.Controls.Add(new LiteralControl("&nbsp;"));

   // Render the >> button
   LinkButton last = new LinkButton();
   last.ID = "Last";
   last.CausesValidation = false;
   last.Click += new EventHandler(last_Click);
   last.Text = " ホイメウ ";
   last.Enabled = isValidPage && canMoveForward;
   cell.Controls.Add(last);

   // Render a drop-down list 
   DropDownList pageList = new DropDownList();
   pageList.ID = "PageList";
   pageList.AutoPostBack = true;
   pageList.SelectedIndexChanged += new EventHandler(PageList_Click);
   pageList.Font.Name = Font.Name;
   pageList.Font.Size = Font.Size;
   pageList.ForeColor = ForeColor;

   // Embellish the list when there are no pages to list
   if (TotalPages <=0 || CurrentPageIndex == -1)
   {
    pageList.Items.Add("");
    pageList.Enabled = false;
    pageList.SelectedIndex = 0;
   }
   else // Populate the list
   {
    for(int i=1; i<=TotalPages; i++)
    {
     ListItem item = new ListItem(i.ToString(), (i-1).ToString());
     pageList.Items.Add(item);
    }
    pageList.SelectedIndex = CurrentPageIndex;
   }
   cell.Controls.Add(pageList);
  }
  // ***********************************************************************

  // ***********************************************************************
  // PRIVATE BuildNumericPagesUI
  // Generates the HTML markup for the Numeric Pages button bar
  private void BuildNumericPagesUI(TableCell cell)
  {
   // Render a drop-down list 
   DropDownList pageList = new DropDownList();
   pageList.ID = "PageList";
   pageList.AutoPostBack = true;
   pageList.SelectedIndexChanged += new EventHandler(PageList_Click);
   pageList.Font.Name = Font.Name;
   pageList.Font.Size = Font.Size;
   pageList.ForeColor = ForeColor;

   // Embellish the list when there are no pages to list
   if (TotalPages <=0 || CurrentPageIndex == -1)
   {
    pageList.Items.Add("No pages");
    pageList.Enabled = false;
    pageList.SelectedIndex = 0;
   }
   else // Populate the list
   {
    for(int i=1; i<=TotalPages; i++)
    {
     ListItem item = new ListItem(i.ToString(), (i-1).ToString());
     pageList.Items.Add(item);
    }
    pageList.SelectedIndex = CurrentPageIndex;
   }
   cell.Controls.Add(pageList);
  }
  // ***********************************************************************
  
  // ***********************************************************************
  // PRIVATE first_Click
  // Event handler for the << button
  private void first_Click(object sender, EventArgs e)
  {
   GoToPage(0);
  }
  // ***********************************************************************

  // ***********************************************************************
  // PRIVATE prev_Click
  // Event handler for the < button
  private void prev_Click(object sender, EventArgs e)
  {
   GoToPage(CurrentPageIndex-1);
  }
  // ***********************************************************************

  // ***********************************************************************
  // PRIVATE next_Click
  // Event handler for the > button
  private void next_Click(object sender, EventArgs e)
  {
   GoToPage(CurrentPageIndex+1);
  }
  // ***********************************************************************

  // ***********************************************************************
  // PRIVATE last_Click
  // Event handler for the >> button
  private void last_Click(object sender, EventArgs e)
  {
   GoToPage(TotalPages-1);
  }
  // ***********************************************************************

  // ***********************************************************************
  // PRIVATE PageList_Click
  // Event handler for any page selected from the drop-down page list
  private void PageList_Click(object sender, EventArgs e)
  {
   DropDownList pageList = (DropDownList) sender;
   int pageIndex = Convert.ToInt32(pageList.SelectedItem.Value);
   GoToPage(pageIndex);
  }
  // ***********************************************************************
  // ***********************************************************************
  // PRIVATE GoToPage
  // Sets the current page index
  private void GoToPage(int pageIndex)
  {
   // Prepares event data
   PageChangedEventArgs e = new PageChangedEventArgs();
   e.OldPageIndex = CurrentPageIndex;
   e.NewPageIndex = pageIndex;

   // Updates the current index
   CurrentPageIndex = pageIndex;

   // Fires the page changed event
   OnPageIndexChanged(e);

   // Binds new data
   DataBind();
  }
  // ***********************************************************************
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值