Quantcast
Viewing all 7205 articles
Browse latest View live

ASPxGridView - How to implement ASPxProgressBar in DataCell with a custom color

This example demonstrates how to define ASPxProgressBar in a column's DataItemTemplate and specify the progress bar color based on a custom criteria.

1) Define ASPxProgressBar in a grid column's DataItemTemplate;

2) Handle the ASPxProgressBar.DataBound event and set color via the ASPxProgressBar.IndicatorStyle.BackColor property based on a column value (or another custom criteria).


ASPxDateEdit - How to close calendar when date is selected if TimeSection is visible

If the time section is enabled ASPxDateEdit does not close the calendar's popup when a user selects a date to allow him to select time. This example demonstrates how to change this behavior and close the calendar's popup immediately after selecting a date.

ASPxGridView - How to make field editors read-only/editable when editing or adding a row

This example demonstrates how to set the editor's ReadOnly property based on the grid's state. I.e. it is possible can edit field value while adding a new row, but this editor becomes ReadOnly if we trying to edit existing row.


It is used the ASPxGridView.CellEditorInitialize event to implement this scenario:

[C#]
protectedvoidgridView_CellEditorInitialize(objectsender,DevExpress.Web.ASPxGridView.ASPxGridViewEditorEventArgse){ASPxGridViewgrid=senderasASPxGridView;if(e.Column.FieldName=="CategoryID")e.Editor.ReadOnly=!grid.IsNewRowEditing;}

Question Comments

Added By: Ju Yeong Jeong at: 1/15/2015 1:00:32 AM    

It's so good example.

Thank you so much !!!

[ASPX]

<dx:ASPxGridView ID="grid" ClientInstanceName="grid" ....
KeyFieldName="MST_CD" OnCellEditorInitialize="grid_CellEditorInitialize">

<dx:ASPxGridView ID="gridDetail" ClientInstanceName="gridDetail" ....
KeyFieldName="MST_CD;CD" OnCellEditorInitialize="grid_CellEditorInitialize">

[C#]
   protected DataTable dtGrid = null;
   protected DataTable dtGridDetail = null;

   protected void Page_Load(object sender, EventArgs e)
   {
       if (! Page.IsPostBack)
       {
               //GET DATATABLE
               dtGrid = dataset.Tables[0];
               //SET PRIMARY KEY(S)
               dtGrid.PrimaryKey = new DataColumn[] { dtGrid.Columns["MST_CD"] };
               //SET SESSION
               Session["DataSet"] = dtGrid;

               dtGridDetail = dataset2.Tables[0];
               dtGridDetail .PrimaryKey = new DataColumn[] { dtGrid.Columns["MST_CD;CD"] };
               Session["DataSetDetail"] = dtGridDetail ;
       }
       else
       {
           dtGrid = (DataTable)Session["DataSet"];
           dtGridDetail = (DataTable)Session["DataSetDetail"];
       }

       grid.DataSource = dtGrid;
       grid.DataBind();

       gridDetail.DataSource = dtGridDetail;
       gridDetail.DataBind();
   }

   /// <summary>
   /// Prevent Editing of the Key Column(s) on Cell Updating
   /// </summary>
   /// <param name="sender"></param>
   /// <param name="e"></param>
   protected void grid_CellEditorInitialize(object sender, ASPxGridViewEditorEventArgs e)
   {
       ASPxGridView oGrid = sender as ASPxGridView;

       string sSession = string.Empty;

       if ("grid" == oGrid.ClientInstanceName )
       {
           sSession = "DataSet";
       }
       else if ("gridDetail" == oGrid.ClientInstanceName)
       {
           sSession = "DataSetDetail";
       }

       DataTable oDt = (DataTable)Session[sSession];
       
       for (int i = 0; i < oDt.PrimaryKey.Length; i++)
       {
           if (e.Column.FieldName == oDt.PrimaryKey[i].ColumnName)
           {
               e.Editor.ReadOnly = !oGrid.IsNewRowEditing;
               return;
           }
       }
   }

Added By: Quasar Wong at: 5/3/2015 9:00:10 PM    

Hi! I am using Batch Edit mode but CellEditorInitialize event will not fired when clicking New button, any other method can do this scenario else? Thanks!

Added By: Larry (DevExpress Support) at: 5/3/2015 10:55:45 PM    

Hello,

To process your recent post more efficiently, I created a separate ticket on your behalf: T237217: ASPxGridView - Batch Editing - The CellEditorInitialize event will not fired when clicking New button. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.

Added By: Ravi Anand 1 at: 6/1/2016 12:34:16 AM    Hi, i have applied given example in ASP.NET MVC, folllwing is my gridview settings sample partial code:

[C#]
settings.CellEditorInitialize=(s,e)=>{ASPxGridViewgrid=sasASPxGridView;ASPxEditeditor=(ASPxEdit)e.Editor;if(e.Column.FieldName=="columnName1"||e.Column.FieldName=="columnName2"){e.Editor.ReadOnly=!grid.IsNewRowEditing;}};

now i can't edit while updating existing row data, that seems perfect.

but i can't edit both columns while creating new row using new button. please help me out here. Thank you in advance. Added By: Stason (DevExpress Support) at: 6/1/2016 6:04:51 AM    

Hello Ravi, 

Since your last post is related to ASP.NET MVC, I've created a separate ticket on your behalf (T386483: GridView - How to apply an approach from the E5116 example to edit columns when a new row is being created). It has been placed in our processing queue and will be answered shortly.

Added By: william sutphin 1 at: 7/5/2017 6:52:06 AM    How do you hide the whole column?Added By: Larry (DevExpress Support) at: 7/6/2017 4:52:15 AM    

Hello,

I've created a separate ticket on your behalf (T533092: ASPxGridView - How to hide some field editors when editing a row and allow their editing when adding a new row). It has been placed in our processing queue and will be answered shortly.

ASPxSplitter - How to manipulate objects inside a pane with the ContentUrl property

This example demonstrates how to manipulate the client-side programmatic objects inside ASPxSplitter's pane with a specified ContentUrl property.

- Get the content IFrame from ASPxSplitter's pane with a specified ContentUrl property viathe ASPxClientSplitterPane.GetContentUrlmethod;
- Get the underlying content window object of this IFrame via the contentWindowproperty;
- Get the required object from this window and manipulate it.

How to set ASPxTextBox.Text inside a pane with a specified ContentUrl property.

ContentPageWithTextbox.aspx:

[ASPx]
<dx:ASPxTextBoxID="tbContent"runat="server"Width="170px"ClientInstanceName="clientTbContent"></dx:ASPxTextBox>


Default.aspx:

[ASPx]
<dx:ASPxSplitterID="splt"runat="server"ClientInstanceName="splitter"><Panes><dx:SplitterPane><ContentCollection><dx:SplitterContentControlID="SplitterContentControl1"runat="server"><dx:ASPxComboBoxID="cmb"runat="server"ClientInstanceName="clientComboBox"><Items> ... </Items><ClientSideEventsSelectedIndexChanged="OnSelectedIndexChanged"/></dx:ASPxComboBox></dx:SplitterContentControl></ContentCollection></dx:SplitterPane><dx:SplitterPaneContentUrl="~/ContentPageWithTextbox.aspx"Name="pnExternalPage"></dx:SplitterPane></Panes></dx:ASPxSplitter>

[JavaScript]
function OnSelectedIndexChanged(s, e){var contentIFrame = splitter.GetPaneByName("pnExternalPage").GetContentIFrame();var contentIFrameWindow = contentIFrame.contentWindow;var contentTextBox = contentIFrameWindow.clientTbContent;if(contentTextBox) contentTextBox.SetText(s.GetText());}

See Also:
E3614: ASPxSplitter - How to return a value from a page specified via SplitterPane.ContentUrl

Question Comments

Added By: Manuel Paz P at: 6/5/2015 6:36:49 AM    

How to find a control inside contentIFrameWindow?
clientTbContent it's a dinamic control and generates runtime. I have the ID of the control:
"RFCX1"
Obviously this is incorrect: contentIFrameWindow."RFCX1". Does exist a method of contentIFrameWindow to get the control from ID?
I already try getElementById but still not working.

Added By: Larry (DevExpress Support) at: 6/5/2015 8:29:29 AM    

Hello,

To process your recent post more efficiently, I created a separate ticket on your behalf: T251888: ASPxSplitter - How to find a control inside contentIFrameWindow. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.

ASPxGridView - Batch Edit mode - How to remove already selected ComboBox column items

This example illustrates how to remove ComboBox column items already selected in any grid cell, i.e. allow selecting only unique ComboBox values when the Batch edit mode is used.

ASPxGridView - Multi-row editing - How to save changes when a focused row is changed

ASPxGridView - How to sort the CustomizationWindow columns based on their visible index

By design, ASPxGridView orders columns in CustomizationWindow based on a column's caption. Thus, it is necessary to change the column caption to change its order in the CustomizationWindow. Adding an index before the caption allows you to set the custom column order:

[C#]
protectedvoidgridView_BeforeGetCallbackResult(objectsender,EventArgse){intcurrentIndex= 0;foreach(GridViewDataColumncolumningridView.DataColumns){if(column.Visible==false)currentIndex++;stringcaption=System.Text.RegularExpressions.Regex.Replace(column.FieldName,"(?=[A-Z][a-z])|(?<=[a-z])(?=[A-Z])"," ",System.Text.RegularExpressions.RegexOptions.Compiled).Trim();column.Caption=!column.Visible?string.Format("{0}) {1}",currentIndex.ToString("D2"),caption):caption;}}

ASPxGridView - Batch Editing - How to display save and cancel buttons only after editing

UPDATED:

Starting with v16.1, this feature is available out of the box. Please refer to the ASPxGridView, ASPxCardView - Change Save and Cancel buttons' enabled state when an end-user changes a value in BatchEdit mode thread for additional information.

This example demonstrates how to hide the Save changes and Cancel changes buttons, and show them only when an end-user edits any cell or row.
See Also:
ASPxGridView - Batch Editing - How to use external buttons to update data and enable them only when a row/cell has been changed  
MVC Example:
GridView - Batch Editing - How to show save and cancel buttons only when any row/cell has been changed

Question Comments

Added By: Warren Connors 4 at: 4/16/2015 12:55:22 AM    

I was just trying to use some of this code, but the SetButtonsVisibility function does not get a value for var statusBar because there are no elements on the rendered page with class name "StatusBarWithButtons" (did a view source and string search). Has this changed recently?

Added By: Larry (DevExpress Support) at: 4/16/2015 6:28:43 AM    Hello,

It seems that you have created a separate ticket for this issue. Let's continue discussing this issue in the ASPxGridView batch edit confirmation on save thread.

Added By: Warren Connors 4 at: 4/16/2015 8:33:34 AM    

One more thing, though - do you have any examples, or could point me to some pertinent doc, on how to construct the following piece of the ASPxGridView specs in code? I am building the entire ASPxGridView in code dynamically, and I can figure out everything else except the following:

           <Templates>
               <StatusBar>
                   <div style="text-align: right">
                       <dx:ASPxHyperLink ID="hlSave" runat="server" Text="Save changes">
                           <ClientSideEvents Click="function(s, e){ gridView.UpdateEdit(); }" />
                       </dx:ASPxHyperLink>
                       <dx:ASPxHyperLink ID="hlCancel" runat="server" Text="Cancel changes">
                           <ClientSideEvents Click="function(s, e){ gridView.CancelEdit(); SetButtonsVisibility(gridView); }" />
                       </dx:ASPxHyperLink>
                   </div>
               </StatusBar>
           </Templates>

Added By: Larry (DevExpress Support) at: 4/17/2015 12:27:50 AM    

Hello,

To process your recent post more efficiently, I created a separate ticket on your behalf: T231731: ASPxGridView - How to create the StatusBar template dynamically. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.

Added By: Gabriel Joly at: 5/27/2016 11:23:12 AM    I've been working for years with devexpress and this is by far the most complicated things I've ever had to do for such a simple task : Disable 2 buttons (save and cancel) when there is no change to the grid. Is it that hard to create an event that is called after OnBatchEndEdit??? Call it AfterBatchEndEdit and get rid of the horrible javascript setTimeout function that should never ever be in a recent website. I can't believe I'm stuck using it here ...Added By: Artem (DevExpress Support) at: 5/29/2016 11:46:13 PM    

Hi Gabriel,

I'm happy to inform you that this functionality will be available out of the box with our next major release (see ASPxGridView, ASPxCardView - Change Save and Cancel buttons' enabled state when an end-user changes a value in BatchEdit mode). 


ASPxComboBox with Large Data Source - How to show information when no results are found

The Combo Box - Filtering a Large Data Source demo illustrates how to filter ASPxComboBox that contains a lot of records. However, when no result is found, ASPxComboBox does not show any information about it. You can change this behavior by showing an additional popup when no results are found. For this, handle the ASPxComboBox' client-side EndCallback event and show ASPxPopupControl when the combo box has no records:

[JavaScript]
function OnEndCallback(s, e){...if(s.GetItemCount() == 0){ popup.Show();}}

ASPxGridView - How to calculate column values on the client side using DataItemTemplate

This example demonstrates how to calculate column values on the client side via editors inside DataItemTemplate and submit the changes to a datasource.

1) Define ASPxSpinEdit editors inside the "Unit Price" and "Units In Stock" column DataItemTemplate and bind the editors with corresponding column values;
2) Define both an unbound column and ASPxTextBox editors inside its DataItemTemplate to display the results of the calculation;
3) Handle the ASPxGridView.CustomUnboundColumnData event to populate unbound column values;
4) Handle the client-side NumberChanged event of template ASPxSpinEdit and calculate a resultant total value for a corresponding DataRow;
5) Track all the modifications via the ASPxHiddenField control;
6) Perform a postback to the server and submit all the changes to the datasource: retrieve the changes from the ASPxHiddenField control.

See Also:
E2961: How to sum values of bound and unbound columns and calculate a total value on the client side

How to implement the Copy/Paste feature

Starting with version 17.2, pasting data from the Clipboard is supported out of the box. To enable this feature, set the GridView.OptionsClipboard.PasteMode property to Update or Append. In this case, you can paste data by pressing CTRL+V or using the GridView.PasteFromClipboard method. 

If you are using an older version, you can paste data manually using the GridView.SetRowCellValue method. To download the example for old versions, select a required version range in the combo box.


Image may be NSFW.
Clik here to view.


See Also:

How to implement the paste from clipboard feature

Question Comments

Added By: Ken Nguyen 6 at: 2/12/2015 10:23:53 AM    

Is this still the method I should follow for the latest version of the winforms gridcontrol?

Added By: Sasha (DevExpress Support) at: 2/13/2015 12:00:59 AM    

Hello Joe,
Yes, use this example to implement the copy/paste feature.

Added By: Chris D at: 7/31/2015 12:37:04 AM    

Dear,

i need to do this with all my gridviews with datasource XPCOLLECTION, what do i have to do ?
Thanks for your support!

Added By: Svetlana (DevExpress Support) at: 7/31/2015 2:12:24 AM    

Hello,

To process your recent post more efficiently, I created a separate ticket on your behalf: T273510: How to implement the Copy/Paste feature with XPCollection in a grid. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.

Added By: Balnur Duisenbayeva at: 8/25/2015 3:19:25 AM    

Hi, support team!

1) Some of my columns are binded to another tables in a datasource with lookup edit, where it gets its values. While copying and pasting a row, there is a FormatException, because columns valuemember is int, display member is string. How can it be solved?

2) It also throws exception ArgumentException, when pasting empty cell of type DateTime. It is not leaving empty Datetime cell as empty in pasted row, says "String was not recognized as a valid Datetime.."

Thank you very much!

Added By: Nadezhda (DevExpress Support) at: 8/25/2015 4:56:30 AM    

Hello,

To process your recent post more efficiently, I created a separate ticket on your behalf: While copying and pasting a row, there is a FormatException, because columns valuemember is int, display member is string. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.

How to reorder grid rows by drag and drop

This example extends the example provided in the How to allow an end-user to move the rows in a grid up and down if the grid is bound to a DataTable article and illustrates how to reorder rows by drag and drop.

Starting with version 17.2.4, you can attach Drag And Drop Behavior to GridControl to implement reordering. For this, handle the DragOver and DragDrop events of the corresponding behavior using the following code:

[C#]
DragDropBehaviorgridControlBehavior=behaviorManager1.GetBehavior<DragDropBehavior>(gridView);gridControlBehavior.DragDrop+=Behavior_DragDrop;gridControlBehavior.DragOver+=Behavior_DragOver;

 

[VB.NET]
Dim gridControlBehavior As DragDropBehavior = behaviorManager1.GetBehavior(Of DragDropBehavior)(Me.gridView1)AddHandler gridControlBehavior.DragDrop, AddressOf Behavior_DragDropAddHandler gridControlBehavior.DragOver, AddressOf Behavior_DragOver

In the DragOver event handler, calculate drag-drop parameters (InsertType, InsertIndicatorLocation, Action and Cursor) using the static DragOverGridEventArgs.GetDragOverGridEventArgs method:

[C#]
privatevoidBehavior_DragOver(objectsender,DragOverEventArgse){DragOverGridEventArgsargs=DragOverGridEventArgs.GetDragOverGridEventArgs(e);e.InsertType=args.InsertType;e.InsertIndicatorLocation=args.InsertIndicatorLocation;e.Action=args.Action;Cursor.Current=args.Cursor;args.Handled=true;}
[VB.NET]
PrivateSub Behavior_DragOver(ByVal sender AsObject, ByVal e As DragOverEventArgs)Dim args As DragOverGridEventArgs = DragOverGridEventArgs.GetDragOverGridEventArgs(e) e.InsertType = args.InsertType e.InsertIndicatorLocation = args.InsertIndicatorLocation e.Action = args.Action Cursor.Current = args.Cursor args.Handled = TrueEndSub

Data Source reordering logic should be implemented in the DragDrop event handler.

In older versions, reordering is implemented using the standard Drag events.

Question Comments

Added By: Micha Ben-Efraim at: 6/11/2012 2:11:54 AM    

I copied this example for reordering the element of a list bound to the control and it works almost perfectly. The problem is that the control doesn't scroll during D&D: the list is longer as the displayed window. If I select the first or the last item in the list (first/last row) and want o move to the last/first position, which is not visible, the view should scroll somehow in order to show the target drop row. But it doesn't do it when I move the cursor to the top/bottom of the view.
Can it

Added By: Fmonteiro at: 11/5/2013 3:34:26 AM    

Is possible to make this with the AdvBandedGridView?
I've tryed to make the same but in the:
Private Sub GridControl1_DragOver(sender As System.Object, e As System.Windows.Forms.DragEventArgs) Handles GridControl1.DragOver
    ' If e.Data.GetDataPresent(GetType(GridHitInfo))

allways returns False, so never enters the IF.

Added By: softwaresupport@smec.com softwaresupport@smec.com at: 6/4/2014 5:43:37 AM    

Hi created a new ticket for this implementation as i dont find that it works

Added By: softwaresupport@smec.com softwaresupport@smec.com at: 6/4/2014 5:44:03 AM    

Here is the ticket ID : T114366

Added By: Nikita (DevExpress Support) at: 6/4/2014 11:29:33 PM    

Hello,
Ok, let's continue our discussion in this ticket.

Added By: Miles Young at: 2/6/2015 7:34:33 AM    

Hi,

This works fine for me after I changed my "Order" column to decimal in my database.

I'd like to know how to change this value and make sure that RowUpdated() is fired though, like when I edit a row normally.

Thanks for this example.

M.Young

Added By: Svetlana (DevExpress Support) at: 2/6/2015 9:25:03 AM    Hi, 

We are already working on your inquiry in the How to force row update thread you created. We will answer you there. Please do not create duplicate posts. Thank you for your understanding. Added By: Dharmesh Jajal 1 at: 10/1/2015 3:53:16 PM    

Please post a solution if the datasource is not a datatable or dataset and is List<SomeRecord>.

Added By: Alisher (DevExpress Support) at: 10/2/2015 12:41:39 AM    

Hello,

To process your recent post more efficiently, I created a separate ticket on your behalf: T296044: Please post a solution if the datasource is not a datatable or dataset and is List<SomeRecord>. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.

Added By: Stefan R at: 2/28/2018 12:22:08 AM    Hello,
can you please please post a solution if the Datasource is a BindingSource?
(i use a mdb file as database)
thx Stefan Added By: Sasha (DevExpress Support) at: 2/28/2018 4:59:17 AM    Hello Stefan,

To complete this task, obtain the underlying DataTable object from BindingSource used as the Grid's data source. You can find an example that illustrates this approach in the GridControl - Modify the E764 example to use it with BindingSource instead of DataTable thread. We will also consider updating this example in order to make it work with any data source. 

Should you have further questions, let me know.Added By: Stefan R at: 2/28/2018 6:36:18 AM    

Hello Sasha,
thank you for your answer.
I tried the E764 example but if i use my existing BindingSource I get a conversion issue on this line:

Dim oldRow As Customer = sourceTable(oldRowIndex)

System.InvalidCastException: 'The object of type' System.Data.DataRowView 'can not be converted to type' SRDCM.Customer '.'

Maby you can help?

Added By: Stefan R at: 2/28/2018 6:49:50 AM    Hello Sasha,
I have modified the example E764 and added my Bindingsource to it.
Can you check this please?
Maby you can find also a solution to save the changes to the Database after Drag&Drop?

https://www.dropbox.com/s/kpl1v6q2xyqv0x0/E764.zip?dl=0

Thx, Stefan Added By: Sasha (DevExpress Support) at: 3/1/2018 2:47:57 AM    

Hello Stefan,
I believe it will be more suitable to discuss this in a separate thread so I've created a new ticket on your behalf: Use the E764 example with BindingSource as the Grid's data source.
I will address it shortly.

How to synchronize the column width when ContentDetailDescriptor is used

This example demonstrates how to implement column width synchronization in Master-Detail DXGrid mode with ContentDetailDescriptor.

In this example, we have created a DetailSyncBehavior class that performs synchronization between Master Grid columns and Detail Grid columns, in accordance with the visible indexes of columns.

This class can easily be attached to the Detail GridControl object in the following manner:

[XAML]
           <dxg:ContentDetailDescriptor>                     <dxg:ContentDetailDescriptor.ContentTemplate>                         <DataTemplate>                             <dxg:GridControlItemsSource="{Binding Details}"AutoGenerateColumns="AddNew"MaxHeight="150">                                 <i:Interaction.Behaviors>                                     <local:DetailSyncBehavior/>                                 </i:Interaction.Behaviors>                                 <dxg:GridControl.View>                                     <dxg:TableViewShowGroupPanel="False"/>                                 </dxg:GridControl.View>                             </dxg:GridControl>                         </DataTemplate>                     </dxg:ContentDetailDescriptor.ContentTemplate>                 </dxg:ContentDetailDescriptor>

 

How to use the SvgImageSource extension to specify a vector image as BarButtonItem's glyph

The SvgImageSource extension allows you to specify a vector image as BarButtonItem's glyph . You can reference a resource in xaml as follows:
[XAML]
Glyph="{dx:SvgImageSourceUri=Images/Notebook.svg}"
where dxis the xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" namespace.
Question Comments

Added By: David Lemieux at: 9/8/2016 5:05:32 AM    Is this supposed to work when the extension is used from inside a DataTemplate, which in turn is within a ResourceDictionary in a file from another assembly? Will the uri be resolved relatively to the RD file location?Added By: Andrey Marten (DevExpress Support) at: 9/8/2016 7:07:24 AM    
Hello David,

I see that I missed a similar question in your thread (T424596). Please accept my apologies for that. I hope you wouldn't mind if I answer you there.
I've updated both your description and my answer in that thread. Take a moment to review it and let me know if you have other questions. 


Thanks,
Andrey

How to export different report groups to different sheets in an XLS file

This example illustrates how to use the Microsoft.Office.Interop.Excel.dll to export different groups in the report onto different sheets.

We have implemented the S33129 suggestion with the v2009 vol 3 version of the suite, which provides build-in capability to accomplish this task.

Question Comments

Added By: Scott Gross at: 4/25/2014 4:00:10 PM    

This code seems to name the Excel sheets by category name. I see in the documentation it says excel sheet names are only named 1,2,3,4,etc with a constant as the sheet name prefix. Do you have any straightforward solution to name the sheet names by grouped band or something similar?


How to implement the "characters remaining" functionality for ASPxTextBox and ASPxMemo using MaxLength

When inputting a value into a text box whose maximum length is limited, it could be useful for end-users to know how many characters they still can type. This example demonstrates how to implement this feature.

The number of remaining characters is printed on a label near the editor. In this example we're using the MaxLength property of the ASPxTextBox, which allows us to specify the maximum length of the ASPxTextBox control. However, the ASPxMemo does not have this property, because the <textarea> HTML element doesnt support a native maxlength attribute. That's why the MaxLength-functionality for the ASPxMemo is implemented here in a roundabout way using a timer to check every 50ms of the memo text's length and trim the text if necessary.

See also:
ASPxMemo - How to limit the length of text that can be entered into the control using MaxLength
How to set the text max length in the ASPxMemo control

Question Comments

Added By: Jun Zhai at: 3/1/2018 6:51:45 AM    do you have a MVC version sample?

How to use the Query Builder in a WinForms application

This example illustrates how to invoke the Query Builder in a WinForms application using the following methods of the SqlDataSourceUIHelper class:
AddQueryWithQueryBuilder
EditQueryWithQueryBuilder
These methods' parameters include a QueryBuilderEditQueryContext instance and custom QueryBuilderRunner implementation that define various Query Builder options.

After adding a new query using the Query Builder in this sample application, click Fill to populate the Grid Control with the query's data.
Question Comments

Added By: Chris D at: 3/3/2018 12:25:09 AM    Dear, 

I need to see / edit the customSQL, too. In Dashboard, i have to set this

DashboardDataSourceWizardSettings.EnableCustomSql

What do I have to do here ?

TX !


How to edit the SqlDataSource connection and query at runtime via wizard by using the SqlDataSourceUIHelper class

This example demonstrates how to use the SqlDataSourceUIHelper class to give the End-User a capability to edit the SqlDataSource component's connection or queries at runtime via wizards.

To execute a connection configuration wizard, call the SqlDataSourceUIHelper.ConfigureConnection method and pass the SqlDataSource component instance to it.
To execute a query editing wizard, call the SqlDataSourceUIHelper.EditQuery method and pass the SqlDataSource component's SqlQuery instance to it. 
Note that it is necessary to refill the SqlDataSource after its connection or query was edited. Use the SqlDataSource.Fill method for this purpose.

Finally, I would like to mention that the SqlDataSourceUIHelper class also provides other wizards that can be used to configure the SqlDataSource component. Please refer to the SqlDataSourceUIHelper Members help topic for more information regarding this.



See also:
Binding to SQL Data
T291969: SqlDataSource - How to change connection parameters at runtime
Question Comments

Added By: Chris D at: 3/3/2018 12:50:37 AM    Dear, 

I am coming from T553576 and wondering which approach is the "best" one. I vote for yours. Nevertheless I have one important question, how can i read the plain SQL-Text to save it as a string?

Tx a lot!

How to generate a sequential number for a persistent object within a database transaction (XAF)

This example illustrates one of the possible approaches to implementing an identifier field with sequential values. Alternate approaches are listed in the An overview of approaches to implementing a user-friendly sequential number for use with an XPO business class KB article.

Scenario

This is a variation of the How to generate and assign a sequential number for a business object within a database transaction, while being a part of a successful saving process XPO example, which was specially adapted for XAF applications.

In particular, for better reusability and more smooth integration with the standard XAF CRUD Controllers, all the required operations to generate sequences are managed within the base persistent class automatically when a persistent object is being saved. For more developer convenience, this solution is organized as a reusable XAF module - GenerateUserFriendlyId.Module. This module consists of several key parts:

    - Sequence and SequenceGenerator are auxiliary classes that take the main part in generating user-friendly identifiers. Take special note that the SequenceGenerator.Initialize method must be called during your XAF application startup for the correct operation.

    - UserFriendlyIdPersistentObject is a base persistent class that subscribes to XPO's Session events and delegates calls to the core classes above. Normally, you must inherit your own business classes from this base class to get the described functionality in your project.

    - IUserFriendlyIdDomainComponent is a base domain component that should be implemented by all domain components that require the described functionality.

Check the original example description first for more information on the demonstrated scenarios and functionality.


Image may be NSFW.
Clik here to view.



Steps to implement
1. Copy and include the GenerateUserFriendlyId.Module project into your solution and make sure it is built successfully.  Invoke the Module or Application Designer for the YourSolutionName.Module/Module.xx  or YourSolutionName.Wxx/WxxApplication.xx files by double-clicking it in Solution Explorer. Invoke the Toolbox (Alt+X+T) and then drag & drop the GenerateUserFriendlyIdModule component into the modules list on the left.

2. For apps with no security or with the Client-Side Security (XPObjectSpaceProvider or SecuredObjectSpaceProvider):
In the YourSolutionName.Wxx/WxxApplication.xx files, modify the CreateDefaultObjectSpaceProvider method to call the SequenceGenerator.Initialize method as shown in the Demo.Wxx\WxxApplication.xx files:

[C#]
...protectedoverridevoidCreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgsargs){GenerateUserFriendlyId.Module.Utils.SequenceGenerator.Initialize(this,args.ConnectionString);//!!!...}

For apps with the Middle Tier Security (DataServerObjectSpaceProvider):
In the YourSolutionName.ApplicationServer project, locate and modify the serverApplication_CreateCustomObjectSpaceProvider or CreateDefaultObjectSpaceProvider  methods to call the SequenceGenerator.Initialize method as shown below:

[C#]
privatestaticvoidserverApplication_CreateCustomObjectSpaceProvider(objectsender,CreateCustomObjectSpaceProviderEventArgse){GenerateUserFriendlyId.Module.SequenceGenerator.Initialize((XafApplication)sender,e.ConnectionString);

In the same code file, locate the serverApplication.Dispose(); line and move to the end of the Main or OnStop methods in the Console or Windows Service applications respectively (in the latter case, the "serverApplication" variable must also be declared in the higher scope).


3.
 If you are using pure XPO classes, then inherit your required business classes from the module's UserFriendlyIdPersistentObject one and use the derived SequenceNumber property as required:

[C#]
publicclassContact:GenerateUserFriendlyId.Module.BusinessObjects.UserFriendlyIdPersistentObject{[PersistentAlias("concat('C', ToStr(SequentialNumber))")]publicstringContactId{get{returnConvert.ToString(EvaluateAlias("ContactId"));}}

If you are using DC interfaces, then implement the IUserFriendlyIdDomainComponent interface by your custom domain component:

[C#]
publicinterfaceIDocument:GenerateUserFriendlyId.Module.BusinessObjects.IUserFriendlyIdDomainComponent{[Calculated("concat('D', ToStr(SequentialNumber))")]stringDocumentId{get;}

Additionally for DC, use the UserFriendlyIdPersistentObject as a base class during your custom domain component registration, e.g.:

[C#]
XafTypesInfo.Instance.RegisterEntity("Document",typeof(IDocument),typeof(GenerateUserFriendlyId.Module.BusinessObjects.UserFriendlyIdPersistentObject));

Note that the sequential number functionality shown in this example does not work with DC shared parts , because it requires a custom base class, which is not allowed for shared parts.

4. For more information, download and review the Address, Contact, and IDocument types within the Demo.Module project. These are test business objects that demonstrate the use of the described functionality for XPO and DC respectively. A required format for the user-friendly identifier property in these end classes is defined within an aliased property (ContactId in the example above) by concatenation of a required constant or dynamic value with the SequentialNumber property provided by the base UserFriendlyIdPersistentObject class. So, if you need to have a different format, modify the PersistentAliasAttribute expression as your business needs dictate.

 

IMPORTANT NOTES

1. As an alternative, you can implement much simpler solutions at the database level or by using the built-in DistributedIdGeneratorHelper.Generate method. Refer to the An overview of approaches to implementing a user-friendly sequential number for use with an XPO business class article for more details.

2.  In the Integrated Mode and middle-tier Application Server scenario the newly generated sequence number will appear in the DetailView only after a manual refresh (i.e., it will be empty right away after saving a new record), because the sequence is generated on the server side only and is not passed to the client. You can download a ready test project for these configurations here. See also the "Refresh the Identifier field value in UI" section in this KB article.
3. You can specify or seed the initial sequence value manually: either by editing the Sequence table in the database or using the standard XPO/XAF means by manipulating the Sequence objects, e.g.:

[C#]
using(IObjectSpaceos=Application.CreateObjectSpace(typeof(Sequence))){Sequencesequence=os.FindObject<Sequence>(CriteriaOperator.Parse("TypeName=?",typeof(E2829).FullName));sequence.NextSequence= 5;os.CommitChanges();}

See also:
How to create multiple sequences based on the a class property value, not one sequence per class type


Your feedback is needed!
We would greatly appreciate it if you share your feedback here in comments or rather participate in this short survey (~3 min).

Question Comments

Added By: Mr. Murat YILMAZ at: 10/7/2012 9:15:18 AM    

Thanks for the example. I developed ISequentialNumber domain component which based on this article and code. Now this sequential number functonatility shon in this example work with domain components and shared parts.

using System;
using System.Collections.Generic;
using System.ComponentModel;

using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Base;
using DevExpress.Xpo;
using DevExpress.Xpo.Metadata;
using DevExpress.ExpressApp;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;

using MyWay.Xaf.Module;
using MyWay.Xaf.Utils.Sequence;

namespace MyWay.Xaf.Module
{
    [DomainComponent]
    [NavigationItem]
    public interface ISequentialNumber
    {
        #region PROPERTIES

        #region SequentialNo

        [Persistent]
        string SequentialNo
        {
            get;
        }

        #endregion SequentialNo

        #region SequentialNumber
        
        [System.ComponentModel.Browsable(false)]
        [Indexed(Unique = false)]
        long SequentialNumber
        {
            get ;
            set;
        }

        #endregion SequentialNumber

        #endregion PROPERTIES
    }

    [DomainLogic(typeof(ISequentialNumber))]
    public class ISequentialNumberLogic
    {

            public static string Get_SequentialNo(ISequentialNumber instance)
            {
                return "asd" + instance.SequentialNumber.ToString();
            }

            

        private static object syncRoot = new object();
        private static SequenceGenerator sequenceGenerator;

        #region METHODS

        #region PUBLIC METHODS

        #region GenerateSequence

        public static void GenerateSequence(ISequentialNumber instance)
        {
            lock (syncRoot)
            {
                Dictionary<string, bool> typeToExistsMap = new Dictionary<string, bool>();

                foreach (object item in ((XPBaseObject)instance).Session.GetObjectsToSave())
                {
                    typeToExistsMap[((XPBaseObject)instance).Session.GetClassInfo(item).FullName] = true;
                }

                if (sequenceGenerator == null)
                {
                    sequenceGenerator = new SequenceGenerator(typeToExistsMap);
                }

                SubscribeToEvents(((XPBaseObject)instance).Session);
                OnSequenceGenerated(sequenceGenerator.GetNextSequence(((XPBaseObject)instance).ClassInfo), instance);
            }
        }

        #endregion GenerateSequence

        #endregion PUBLIC METHODS

        #region PROTECTED METHODS

        #region OnSaving

        public static void OnSaving(ISequentialNumber instance)
        {
            try
            {
                //base.OnSaving();
                if (((XPBaseObject)instance).Session.IsNewObject(instance) && !typeof(NestedUnitOfWork).IsInstanceOfType(((XPBaseObject)instance).Session))
                {
                    GenerateSequence(instance);
                }
            }
            catch
            {
                CancelSequence(((XPBaseObject)instance).Session);
                throw;
            }
        }

        #endregion OnSaving

        #endregion PROTECTED METHODS

        #region INTERNAL METHODS

        #endregion INTERNAL METHODS

        #region PRIVATE METHODS

        #region AcceptSequence

        private static void AcceptSequence(Session session)
        {
            lock (syncRoot)
            {
                if (sequenceGenerator != null)
                {
                    try
                    {
                        sequenceGenerator.Accept();
                    }
                    finally
                    {
                        CancelSequence(session);
                    }
                }
            }
        }

        #endregion AcceptSequence

        #region CancelSequence

        private static void CancelSequence(Session session)
        {
            lock (syncRoot)
            {
                UnSubscribeFromEvents(session);
                if (sequenceGenerator != null)
                {
                    sequenceGenerator.Close();
                    sequenceGenerator = null;
                }
            }
        }

        #endregion CancelSequence

        #region Session_AfterCommitTransaction

        private static void Session_AfterCommitTransaction(object sender, SessionManipulationEventArgs e)
        {
            
            AcceptSequence(e.Session);
        }

        #endregion Session_AfterCommitTransaction

        #region Session_AfterRollBack

        private static void Session_AfterRollBack(object sender, SessionManipulationEventArgs e)
        {
            CancelSequence(e.Session);
        }

        #endregion Session_AfterRollBack

        #region Session_FailedCommitTransaction

        private static void Session_FailedCommitTransaction(object sender, SessionOperationFailEventArgs e)
        {
            CancelSequence((Session)sender);
        }

        #endregion Session_FailedCommitTransaction

        #region SubscribeToEvents

        private static void SubscribeToEvents(Session session)
        {
            if (!(session is NestedUnitOfWork))
            {
                session.AfterCommitTransaction += Session_AfterCommitTransaction;
                session.AfterRollbackTransaction += Session_AfterRollBack;
                session.FailedCommitTransaction += Session_FailedCommitTransaction;
            }
        }

        #endregion SubscribeToEvents

        #region UnSubscribeFromEvents

        private static void UnSubscribeFromEvents(Session session)
        {
            if (!(session is NestedUnitOfWork))
            {
                session.AfterCommitTransaction -= Session_AfterCommitTransaction;
                session.AfterRollbackTransaction -= Session_AfterRollBack;
                session.FailedCommitTransaction -= Session_FailedCommitTransaction;
            }
        }

        #endregion UnSubscribeFromEvents

        #region OnSequenceGenerated

        private static void OnSequenceGenerated(long newId, ISequentialNumber instance)
        {
            instance.SequentialNumber = newId;
        }

        #endregion OnSequenceGenerated

        #endregion PRIVATE METHODS

        #endregion METHODS
    }
}

Added By: Luis Alberto Santiago at: 2/25/2013 8:06:36 PM    

Hi Mr. Murat YILMAZ, Can yo provide some example to use the class. I am looking it for shared parts

Added By: Andrew Bingham 2 at: 7/8/2013 3:38:51 AM    

I implemented this OK in a Solution

When I eimplmented it in a different solution I got an Exception
"Message: Value cannot be null.
Parameter name: Application"

thrown at:

    public static void Initialize() {
            Guard.ArgumentNotNull(Application, "Application");

Added By: Dennis (DevExpress Support) at: 7/11/2013 3:11:06 AM    

@Andrew: You forgot to add the following code:

public override void Setup(XafApplication application) {
            base.Setup(application);
            SequenceGeneratorInitializer.Register(application);
        }

You will not experience this and similar difficulties if you simply add the reusable module into your solution as per instructions above.

Added By: Carlitos at: 8/23/2014 6:46:05 PM    

Hi,
Is this now supported in Middle-Tier XAF applications?

Thanks,

Carlitos

Added By: Dennis (DevExpress Support) at: 8/25/2014 4:38:12 AM    

We have not performed additional R&D and testing of this particular example in a middle-tier scenario. Moreover, I see technical problems using this particular solution in this configuration, because here we use ExplicitUnitOfWork, which implies that it will be a sole owner of the database connection. Probably, for this configuration, it is better to stick to a standard solution, e.g. using database triggers. 

Added By: Carlitos at: 8/25/2014 9:34:23 AM    

Hi Dennis,
But how does the Middle-tier handle database connections? I thought it would do some sort of connection pooling and manage all client connections?

Why do you think that Triggers are a good alternative?

Carlos

Added By: Dennis (DevExpress Support) at: 8/26/2014 6:14:27 AM    

By default, the middle-tier app server uses ThreadSafeDataLayer to effectively handle requests from multiple clients at the same time. Connection pooling may be used here, but this is not managed by us by default and is rather controller by ADO.NET transparently for a consumer. My main concern here was that in such a multi-user environment it will not be possible to exclusively lock the connection by one user.
A solution at the database level looks more universal as it works at the database level and is irrelevant to whether the app server is used or not. 

Added By: Vishwas Mokashi at: 4/14/2015 11:21:58 AM    

In XAF application I have about 25 various business objects that need to generate unique user friendly sequence numbers in when saved. For example Customer Number, Invoice Number, Order Number, etc. Many users are going to work concurrently and everything should work in transaction.

Which approach should I use, the one in E2620 or E2829?.

I felt E2620 a bit better as I need not to inherit my classes (25 of them) from  UserFriendlyIdPersistentObject as shown in E2829.  

But approach in E2829 is said to be primarily for XAF applications

Added By: Dennis (DevExpress Support) at: 4/15/2015 4:47:25 AM    

@Vishwas: Both E2620  and E2829 demonstrate the same solution using ExplicitUnitOfWork. E2829 is just a bit better integrated with the XAF infrastructure.
If you do not want to inherit from a common base class, I suggest you consider using How to generate a sequential and user-friendly identifier field within a business class, which is simpler to implement and provides similar capabilities without using ExplicitUnitOfWork.

Added By: Vishwas Mokashi at: 4/17/2015 6:54:45 AM    

OK thanks Dennis.

Will simpler approach in "How to generate a sequential and user-friendly identifier field within a business class" handle concurrent users creating same business objects properly?. We can assume about 25 Concurrent users for same business object, with SQL Server DB.

Some users will be accessing system over low banddwidth VPN internet connection. (for Sale Invoice object which needs to generate sequencial Invoice Numbers)

Added By: Dennis (DevExpress Support) at: 4/20/2015 7:58:16 AM    

@Vishwas: Yes, it will. The DistributedIdGeneratorHelper class tries to save a record and repeats its attempts several times until it reaches the maximum number or saves data completely. Check out the corresponding source code for more details on how this works.

    public static class DistributedIdGeneratorHelper {
        public const int MaxIdGenerationAttemptsCounter = 7;
        public static int Generate(IDataLayer idGeneratorDataLayer, string seqType, string serverPrefix) {
            for(int attempt = 1; ; ++attempt) {
                try {
                    using(Session generatorSession = new Session(idGeneratorDataLayer)) {
                        CriteriaOperator serverPrefixCriteria;
                        if(serverPrefix == null) {
                            serverPrefixCriteria = new NullOperator("Prefix");
                        }
                        else {
                            serverPrefixCriteria = new BinaryOperator("Prefix", serverPrefix);
                        }
                        OidGenerator generator = generatorSession.FindObject<OidGenerator>(
                            new GroupOperator(new BinaryOperator("Type", seqType), serverPrefixCriteria));
                        if(generator == null) {
                            generator = new OidGenerator(generatorSession);
                            generator.Type = seqType;
                            generator.Prefix = serverPrefix;
                        }
                        generator.Oid++;
                        generator.Save();
                        return generator.Oid;
                    }
                }
                catch(LockingException) {
                    if(attempt >= MaxIdGenerationAttemptsCounter)
                        throw;
                }
            }
        }Added By: Vishwas Mokashi at: 4/21/2015 6:03:28 AM    

Thanks Dennis

Added By: Konstantin B (DevExpress) at: 12/4/2017 1:20:01 AM    Update: This example illustrates one of the possible approaches to implementing an identifier field with sequential values. Alternate approaches are listed in the An overview of approaches to implementing a user-friendly sequential number for use with an XPO business class KB article.Added By: Cecil Carter at: 3/3/2018 7:30:11 AM    I've tried running the example scenario against a MySQL database and I'm receiving the following error. I assume this is related to the SQL statement generated by the ORM for MySQL. Is there a possible work around to this error?

DevExpress.ExpressApp.Updating.CompatibilityException
  HResult=0x80131509
  Message=Unable to create 'PrimaryKey' 'PK_Sequence'. Parent: 'Sequence'. Error: Executing Sql 'alter table `Sequence` add constraint `PK_Sequence` primary key (`TypeName`)' with parameters '' exception 'MySql.Data.MySqlClient.MySqlException (0x80004005): BLOB/TEXT column 'TypeName' used in key specification without a key length
   at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
   at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
   at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
   at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
   at DevExpress.Xpo.Logger.LogManager.Log[T](String category, LogHandler`1 handler, MessageHandler`1 createMessageHandler)
   at DevExpress.Xpo.DB.ConnectionProviderSql.ExecSql(Query query)'
  Source=DevExpress.ExpressApp.v17.2
  StackTrace:
   at DevExpress.ExpressApp.Updating.DatabaseUpdater.Update()
   at GenerateUserFriendlyId.Win.GenerateUserFriendlyIdWindowsFormsApplication.GenerateUserFriendlyIdWindowsFormsApplication_DatabaseVersionMismatch(Object sender, DatabaseVersionMismatchEventArgs e) in C:\Users\Cecil Carter\Downloads\eXpressApp Framework\17.2.5\E2829\Demo.Win\WinApplication.cs:line 26
   at DevExpress.ExpressApp.XafApplication.OnDatabaseVersionMismatch(DatabaseVersionMismatchEventArgs args)
   at DevExpress.ExpressApp.XafApplication.CheckCompatibilityCore()
   at DevExpress.ExpressApp.XafApplication.CheckCompatibility()
   at DevExpress.ExpressApp.XafApplication.Logon(PopupWindowShowActionExecuteEventArgs logonWindowArgs)
Inner Exception 1:
UnableToCreateDBObjectException: Unable to create 'PrimaryKey' 'PK_Sequence'. Parent: 'Sequence'. Error: Executing Sql 'alter table `Sequence` add constraint `PK_Sequence` primary key (`TypeName`)' with parameters '' exception 'MySql.Data.MySqlClient.MySqlException (0x80004005): BLOB/TEXT column 'TypeName' used in key specification without a key length
   at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
   at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
   at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
   at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
   at DevExpress.Xpo.Logger.LogManager.Log[T](String category, LogHandler`1 handler, MessageHandler`1 createMessageHandler)
   at DevExpress.Xpo.DB.ConnectionProviderSql.ExecSql(Query query)'
Inner Exception 2:
SqlExecutionErrorException: Executing Sql 'alter table `Sequence` add constraint `PK_Sequence` primary key (`TypeName`)' with parameters '' exception 'MySql.Data.MySqlClient.MySqlException (0x80004005): BLOB/TEXT column 'TypeName' used in key specification without a key length
   at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
   at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
   at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
   at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
   at DevExpress.Xpo.Logger.LogManager.Log[T](String category, LogHandler`1 handler, MessageHandler`1 createMessageHandler)
   at DevExpress.Xpo.DB.ConnectionProviderSql.ExecSql(Query query)'
Inner Exception 3:
MySqlException: BLOB/TEXT column 'TypeName' used in key specification without a key length

How to create a text markup annotation and specify its properties

Viewing all 7205 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>