In this example, the ASPxClientTreeList.NodeClick event is handled to display a level of a clicked node in the alert box.
See also:
ASPxTreeList: How to Get Node Level on Client-Side Events
ASPxTreeList does not provide a method to determine the node level on the client side. This example demonstrates how to use the ASPxTreeList JSProperties to create this functionality.
In this example, ASPxTreeList ClientSide Event “NodeClick” is handled to redirect the page if a level-2 node is clicked. The new page shows the NodeKey of the node that is clicked.
See also:
ASPxTreeList - How to get node level on client-side events using HTML attributes
Suppose that it is necessary to provide a capability to work with documents. These documents can have various sets of fields, in various orders. To implement this scenario using standard XAF tools, it is necessary to create a lot of business classes, one for each kind of document. This solution doesn't allow the creation of a new document kind.
This example solves the described above task in the following way:
There is a Document class, which contains fields, common for all documents. It has an associated collection of document items, represented by the DocumentItemBase class and its descendants. To place document items into the Document DetailView, a custom property editor named DocumentItemsPropertyEditor is implemented. It is used for the Document.Items collection and draws a table with editors associated with document items. As a result, it is possible to customize editors shown in the DetailView at runtime.
Note that the example uses the InMemoryDataStoreProvider. To use another database, you need to modify the Session_Start event handler from the Global.asax.cs file.
See Also:
Implement Custom Property Editors
Does not work in edit mode on v12.1.4
Added By: Louis Z at: 5/26/2014 7:12:10 AMThis example fails on 'New'. Run, click new button.
NullReferenceExeption: Object reference not set to an instance of an object.
private void CreateLayoutItems(LayoutControl layout) {
....
for (int i = 0; i < itemsPerRow - columnIndex; i++) {
FAIL --> row.Add(new EmptySpaceItem());
}
This example demonstrates how to use the XL Export API to create spreadsheet files in XLSX, XLS and CSV formats.
This project introduces API properties and methods used to perform the following operations:
- Create a workbook, worksheets, rows, columns and particular cells
- Apply predefined, themed and custom formatting to worksheet cells
- Apply conditional formatting rules
- Enable filtering and group data
- Apply data validation rules
- Assign formulas to worksheet cells
- Specify page settings
- Specify print options
- Insert pictures
- Insert hyperlinks
- Specify document properties
This example demonstrates how to implement a possibility to upload and save different files in Edit mode. In this solution, files are saved to the database. It is also possible to immediately delete a just uploaded file.
This example illustrates how you can bind the XtraScheduler to a collection of custom business objects. To accomplish this task, you should have two collections - one for appointments, another for resources. The appointment collection should implement the IBindingList interface. You can implement this interface manually in your custom collection, but we recommend you use the System.ComponentModel.BindingList<T> collection.
Additionally, your business object should have properties suitable for mapping to the corresponding properties of XtraScheduler's appointments and resources.
Hello,
This sample uses old technology and is needlessly confusing. It is not necessary to manually implement the IBindingList interface. One can use the BindingList<T> class along with a BindingSource. For example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraScheduler;
using System.Linq;
namespace CustomObjectsBinding {
public partial class Form1 : Form {
public static Random RandomInstance = new Random();
private BindingList<CustomResource> m_customResourceBindingList = new BindingList<CustomResource>();
private BindingSource m_customResourceBindingSource = new BindingSource();
private BindingList<CustomAppointment> m_customAppointmentBindingList = new BindingList<CustomAppointment>();
private BindingSource m_customAppointmentBindingSource = new BindingSource();
public Form1() {
InitializeComponent();
schedulerStorage1.Resources.ColorSaving = ColorSavingType.Color;
}
private void Form1_Load(object sender, EventArgs e) {
InitResources();
InitAppointments();
schedulerControl1.Start = DateTime.Now;
UpdateControls();
}
private void InitResources() {
ResourceMappingInfo mappings = this.schedulerStorage1.Resources.Mappings;
mappings.Id = "ResID";
mappings.Color = "ResColor";
mappings.Caption = "Name";
m_customResourceBindingList.Add(CreateCustomResource(1, "Max Fowler", Color.PowderBlue));
m_customResourceBindingList.Add(CreateCustomResource(2, "Nancy Drewmore", Color.PaleVioletRed));
m_customResourceBindingList.Add(CreateCustomResource(3, "Pak Jang", Color.PeachPuff));
m_customResourceBindingSource.DataSource = m_customResourceBindingList;
this.schedulerStorage1.Resources.DataSource = m_customResourceBindingSource;
}
private CustomResource CreateCustomResource(int res_id, string caption, Color ResColor) {
CustomResource cr = new CustomResource();
cr.ResID = res_id;
cr.Name = caption;
cr.ResColor = ResColor;
return cr;
}
private void InitAppointments() {
AppointmentMappingInfo mappings = this.schedulerStorage1.Appointments.Mappings;
mappings.Start = "StartTime";
mappings.End = "EndTime";
mappings.Subject = "Subject";
mappings.AllDay = "AllDay";
mappings.Description = "Description";
mappings.Label = "Label";
mappings.Location = "Location";
mappings.RecurrenceInfo = "RecurrenceInfo";
mappings.ReminderInfo = "ReminderInfo";
mappings.ResourceId = "OwnerId";
mappings.Status = "Status";
mappings.Type = "EventType";
List<CustomAppointment> appointmentList = new List<CustomAppointment>();
GenerateEvents(appointmentList);
m_customAppointmentBindingList = new BindingList<CustomAppointment>(appointmentList);
m_customAppointmentBindingSource.DataSource = m_customAppointmentBindingList;
this.schedulerStorage1.Appointments.DataSource = m_customAppointmentBindingSource;
}
private void GenerateEvents(List<CustomAppointment> eventList) {
int count = schedulerStorage1.Resources.Count;
for (int i = 0; i < count; i++) {
Resource resource = schedulerStorage1.Resources[i];
string subjPrefix = resource.Caption + "'s ";
eventList.Add(CreateEvent(subjPrefix + "meeting", resource.Id, 2, 5));
eventList.Add(CreateEvent(subjPrefix + "travel", resource.Id, 3, 6));
eventList.Add(CreateEvent(subjPrefix + "phone call", resource.Id, 0, 10));
}
}
private CustomAppointment CreateEvent(string subject, object resourceId, int status, int label) {
CustomAppointment apt = new CustomAppointment();
apt.Subject = subject;
apt.OwnerId = resourceId;
Random rnd = RandomInstance;
int rangeInMinutes = 60 * 24;
apt.StartTime = DateTime.Today + TimeSpan.FromMinutes(rnd.Next(0, rangeInMinutes));
apt.EndTime = apt.StartTime + TimeSpan.FromMinutes(rnd.Next(0, rangeInMinutes / 4));
apt.Status = status;
apt.Label = label;
return apt;
}
private void UpdateControls() {
this.radioGroup1.EditValue = (int)schedulerControl1.GroupType;
}
private void radioGroup1_SelectedIndexChanged(object sender, EventArgs e) {
schedulerControl1.GroupType = (SchedulerGroupType)radioGroup1.EditValue;
}
}
}
Then one can use LINQ to Objects and do things like:
List<CustomAppointment> travelList = m_customAppointmentBindingList.Where(x => x.Subject.Contains("travel")).ToList();
etc. Without the need to implement the binding interfaces, the CustomObjects.cs file can be reduced to:
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Collections;
using System.Drawing;
namespace CustomObjectsBinding {
public class CustomAppointment
{
private DateTime m_Start;
private DateTime m_End;
private string m_Subject;
private int m_Status;
private string m_Description;
private long m_Label;
private string m_Location;
private bool m_Allday;
private int m_EventType;
private string m_RecurrenceInfo;
private string m_ReminderInfo;
private object m_OwnerId;
public DateTime StartTime { get { return m_Start; } set { m_Start = value; } }
public DateTime EndTime { get { return m_End; } set { m_End = value; } }
public string Subject { get { return m_Subject; } set { m_Subject = value; } }
public int Status { get { return m_Status; } set { m_Status = value; } }
public string Description { get { return m_Description; } set { m_Description = value; } }
public long Label { get { return m_Label; } set { m_Label = value; } }
public string Location { get { return m_Location; } set { m_Location = value; } }
public bool AllDay { get { return m_Allday; } set { m_Allday = value; } }
public int EventType { get { return m_EventType; } set { m_EventType = value; } }
public string RecurrenceInfo { get { return m_RecurrenceInfo; } set { m_RecurrenceInfo = value; } }
public string ReminderInfo { get { return m_ReminderInfo; } set { m_ReminderInfo = value; } }
public object OwnerId { get { return m_OwnerId; } set { m_OwnerId = value; } }
public CustomAppointment()
{
}
}
public class CustomResource {
private string m_name;
private int m_res_id;
private Color m_res_color;
public string Name { get { return m_name; } set { m_name = value; } }
public int ResID { get { return m_res_id; } set { m_res_id = value; } }
public Color ResColor { get { return m_res_color; } set { m_res_color = value; } }
public CustomResource()
{
}
}
}
Please verify.
Added By: Tejaswi Rana at: 10/24/2013 3:41:59 PMWhat is the bare minimum mapping details necessary to display an appointment? For example, I have an object that only has the properties StartTime, EndTime, Description & Type. I have not linked any resources to any of these objects. And I am using a bindingList<of thisClass>. This is in version 8.3. I don't see any output.
Added By: Tejaswi Rana at: 10/24/2013 6:56:08 PMI will answer the above myself: This works in version 8.3. Actually the comment above helped a lot :).
Also, there is no need to have resources if you're including them within something like "description" of the appointment itself.
You can have as many mappings as you want to send. The only thing to be careful about is if you have a mapping and don't send data or proper data type.
Can you add to this example to show how to add appointments after the initial load? I am using a custom dialog and adding my objects to my source binding list, but they do not appear until I completely reload my gantt chart.
Added By: Andrey (DevExpress Support) at: 9/2/2015 8:18:38 AMHello,
To process your recent post more efficiently, I created a separate ticket on your behalf: T285177: How to refresh the scheduler on adding an appointment in the E750 example. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.
This example demonstrates how to move ASPxGridView rows using buttons or jQuery Drag&Drop.
To keep the order of rows, it is necessary to set up an extra column to store row order indexes. Then, sort ASPxGridView by this column and deny sorting by other columns. This example stores this information in the unbound column and additionally puts a dictionary "row key = row index" to the session. We have implemented this approach only for demo purposes. You can store this information in your DataSource.
Updated:
We updated an example for v.14.2 to show how to save order information to a database and tune the ASPxGridView drag and drop appearance using the UI Draggable and Droppable plug-ins. If you need to check the unbound column implementation, choose the second item in the version build combo box.
See also:
T191258 - How to reorder GridView rows using buttons or drag-and-drop
E1810: How to use jQuery to drag and drop items from one ASPxGridView to another
E3850: How to reorder ASPxTreeList sibling nodes, using buttons or drag-and-drop
E4299: How to move up or down a line a row of ASPxGridView by using external buttons
Hello,
I have seen your example however I have a question from user view point. Once you start to drag a row button you don't have any way to tell which row you are dragging. So unless you remember the row to started with it will be diffcult for users to use this practically. Do you have a way to drag the entire row or have a button with some text to identify the row you are dragging? Please let me know if this is possible.
Added By: Jacob Blumberg at: 8/27/2013 4:05:00 PMI agree, that is what I am looking for too.
Added By: Hiren Joshi (Venture) at: 9/11/2013 10:54:22 AMI was able to use the link tag <a href=""><%#Eval("YourData")%></a> instead of the image; in order to over come the problem of knowing which row is being dragged. So now when I drag the row I can see the text that I am dragging.
Added By: Wouter Stichelbout at: 2/11/2014 7:54:23 AMI there an MVC equivalent?
Added By: Vasily (DevExpress Support) at: 2/11/2014 9:48:17 AMHi Wouter,
I have extracted your question to a separate ticket created on your behalf: Q466606: GridView - How to reorder GridView rows using buttons or drag-and-drop.
Your time and cooperation are appreciated.
Hello,
This approach much more resembles the way Telerik has implemented row dragging and dropping:
function InitalizejQuery() {
var openhand = "url(https://mail.google.com/mail/images/2/openhand.cur), move";
var closedhand = "url(https://mail.google.com/mail/images/2/closedhand.cur), move";
$('.dxgvDataRow, .dxgvFocusedRow').each(function () {
$(this).css({ "cursor": openhand });
});
$('.dxgvDataRow, .dxgvFocusedRow').draggable({
helper: function () {
var result = $("<table class='dxgvTable' cellspacing='0' cellpadding='0' style='opacity:0.7;background-color:#dddddd;'>").append($(this).clone()).append($("</table>"));
$("td", this).each(function (index) {
$("td", result).eq(index).css({ 'width': $(this).width() });
});
return result;
},
axis: "y",
start: function (event, ui) {
$("tr", $(this).parent()).each(function (index) {
$(this).css({ "cursor": closedhand });
$(this).removeClass('dxgvFocusedRow'); // this is the same as removing the focussedrowindex
$(this).addClass('dxgvDataRow');
});
$(this).addClass('dxgvFocusedRow');
},
stop: function (event, ui) {
$(this).css({ "cursor": openhand });
}
});
$('.dxgvDataRow, .dxgvFocusedRow').droppable({
drop: function (event, ui) {
var draggingRowKey = ui.draggable.find("input[type='hidden']").val();
var targetRowKey = $(this).find("input[type='hidden']").val();
gridView.PerformCallback("DRAGROW|" + draggingRowKey + '|' + targetRowKey);
}
, over: function (event, ui) {
var targetRowKey = $(this).find("input[type='hidden']").val();
var rowindex = gridView.keys.indexOf(targetRowKey);
window.setTimeout(function () { gridView.MakeRowVisibleNew(rowindex); }, 100);
$(this).addClass('borderClass');
}
, out: function (event, ui) {
$(this).removeClass('borderClass');
}
});
}
Best Regards,
Ernstjan Freriks
I am having difficulties figuring out how to actually use a field from the datasource to save the sorting order. Any help will be appreciated.
Added By: Artem (DevExpress Support) at: 12/9/2014 12:17:45 AMHello,
To process your post more efficiently, I created a separate ticket on your behalf: T184636: ASPxGridView - How to save sort order to a database using approach from the E4582. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.
Just a suggestion you should also make these for where people load data via datasource in the code behind because trying to translate this sometime to that things get messed up.
Added By: Anthony (DevExpress Support) at: 4/9/2015 1:07:37 PMHi Gregory,
You are always welcome to create a support ticket if you have difficulties in implementing approaches from our examples.
This example does not work if used within a MasterPage. Has anyone tried this?
Added By: Artem (DevExpress Support) at: 9/2/2015 1:14:20 PMHello Michael,
To process your recent post more efficiently, I created a separate ticket on your behalf: T285292: E4582 doesn't work if ASPxGridView in on a MasterPage. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.
Problem:
I need to hide some columns in the GridView because they are utilized for internal purpose (e.g., rowversion column). At the same time, it is necessary to have these column values in the update action method specified via the MVCxGridViewEditingSettings.UpdateRowRouteValues Property. Currently, the corresponding values are empty.
Solution:
This issue occurs because the generated HTML does not contain INPUT fields that correspond to hidden columns. For this reason, when data is posted to the server, the corresponding model fields are left empty (the model binding mechanism cannot find appropriate values for these fields). To solve this problem, you can use the approach from the Passing Values to Controller Action Through Callbacks help section to forcibly pass the required values to the update action method. In addition to the MVCxClientGridView.BeginCallback Event, you need to handle the GridViewSettings.CustomJSProperties Event to pass the currently edited row values to the client side.
Note:
If it is OK for you to show the caption and editor of the hidden column in the Edit Form, you can use a much simpler solution. Just set the GridColumnEditFormSettings.Visible property to true. This approach might be useful when you are hiding columns via the Customization Window.
This example demonstrates how to implement a custom IConnectionStorageService and use it instead of the default one in the data source wizard. This service implementation allows only getting connection parameters from the DashboardDesigner.CustomDataConnection collection. To load the custom service instead of the default one, execute the following code:
[C#]dashboardDesigner1.ServiceContainer.RemoveService(typeof(IConnectionStorageService));dashboardDesigner1.ServiceContainer.AddService(typeof(IConnectionStorageService),newCustomConnectionStorageService(dashboardDesigner1));
This example demonstrates how to swap two rows to move a specific row up or down
This code is great, but does not work if you delete a row. If I have 6 items in the list and I delete item 2, this code doesnt work. How do we make it work in that case. Also, the ordering doesnt work, the numbers change to like 10.5, etc.
Added By: dsk96m at: 9/19/2013 9:09:05 AMNevermind the second part of that. But how do we make this work so i can delete a row.
Added By: Faizan Mubasher at: 9/3/2015 12:37:12 AMThere is a problem! There are rows with dim and visible Expand buttons. Like, if there exist child row then expand button will be proper visible but dim otherwise just like normal grid behavior. But when rows are swapped, expand buttons doesn't change their state accordingly which is wrong and undesirable. Can you sort out the issue?
Added By: Alexey Z (DevExpress Support) at: 9/3/2015 12:55:13 AM Hello,Another issue! What if the Row is expanded and we swap them?
Added By: Alexey Z (DevExpress Support) at: 9/3/2015 1:58:57 AM Hello,This example shows how to create and customize a custom command button. The custom "Filter" button (CardViewCustomCommandButton) is added to the CardViewCommandLayoutItem.CustomButtons collection. To define an action of the custom "Filter" button, the ASPxCardView.CustomButtonCallback event is handled.
This example shows how to access and remove rows by using a custom cell's context menu.
This sample illustrates how you can customize the popup-menu that is shown by the right-click onto the Design panel of the Report Designer.
In particular, it illustrates the process of adding the option of showing and hiding the Designer grid.
WPF: WPF Report Designer - How to customize the reporting popup menu
Hi,
I want to use this approach to remove the "Edit Parameters ..." command from the pop-up menu in the field list. What I came up with looks like this:
public void ProcessMenuItems(MenuKind menuKind, MenuItemDescriptionCollection items)
{
if (menuKind == MenuKind.FieldList)
{
CommandID removeCommand = null;
foreach (var item in items)
{
if (item.CommandID != null && item.CommandID.ID == 6) removeCommand = item.CommandID;
}
if (removeCommand != null) items.Remove(removeCommand);
}
}
Obviously, hard-coding the command ID (6) is not a good solution, but I could not find the corresponding Enum value. Can you help me here?
Marco
Added By: Uwe Philipps at: 10/1/2013 3:33:28 AMWhen using this example I only see the custom menu items on the first time the designer is shown.
When opening the designer again, ProcessMenuItems() is not called and the custom menu items are not shown.
I'm using Visual Studio 2010 and DevExpress Reporting V13.1.7
Added By: Dmitry Tok (DevExpress Support) at: 2/2/2015 12:38:35 AMHello Uwe,
To process your recent post more efficiently, I created a separate ticket on your behalf: T203628: An issue with the E4343 Code Example. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.
This example demonstrates how to expand child rows recursively when a parent group row is expanded. This feature is implemented by handling a client-side RowExpanding event and sending a custom callback.
What this does for me is that it expands the list recursively but then contracts to the first level again in a flash. I tried e.Cancel = true; but that did not help. Can you please help>?
Thaks.
Problem:
I wish to implement custom paging elements with the capability to show all records.
Solution:
Generally, it is possible to override the template for the Pager area using the GridViewSettings.SetPagerBarTemplateContent(Action`1) method. However, in this scenario the entire area with your custom template will be hidden once you set the ASPxGridViewPagerSettings.Mode property to the ShowAllRecords value. This is expected behavior. To overcome it, you can leave the default page UI and add custom pager elements to the Footer area by overriding its template instead using the GridViewSettings.SetFooterRowTemplateContent(Action`1) method.
Note 1: Currently, there is no capability to replicate the default UI of the GridView's specific visual element within a template of this element. We have discussed this topic in the S37728: Add the GridViewTemplateReplacement extension ticket.
Note 2: If necessary, you can display the "Show All Records" item in the "Select Page Size" element of the built-in pager without implementing custom templates:
[C#]@Html.DevExpress().GridView(settings=>{settings.Name="GridView";settings.SettingsPager.PageSizeItemSettings.Visible=true;settings.SettingsPager.PageSizeItemSettings.ShowAllItem=true;...
[VB.NET]@Html.DevExpress().GridView( _Sub(settings) settings.Name = "GridView" settings.SettingsPager.PageSizeItemSettings.Visible = True settings.SettingsPager.PageSizeItemSettings.ShowAllItem = True ...
IMPORTANT NOTE
This article describes some advanced customization techniques and low-level entities of the framework with regard to data access, which may be required in complex scenarios only.
So, if you just want to change the connection string, e.g. to use the Oracle instead of the Microsoft SQL Server database, then you would better refer to the Connect an XAF Application to a Database Provider article and documentation on your database provider instead. The XAF integration of supported ORM libraries is also described in the Business Model Design section of the framework's documentation.
Introducing IObjectSpaceProvider and IObjectSpace
XAF accesses data from a data store through special abstractions called - IObjectSpaceProvider and IObjectSpace.
The IObjectSpace is an abstraction above the ORM-specific database context (e.g., the DBContext used in Entity Framework or the Session in XPO) allowing you to query or modify data.
The IObjectSpaceProvider is a provider/creator of IObjectSpace entities, which also manages which business types these IObjectSpace are supposed to work with, how to set up the underlying connection to the database, create and update it and other low level data access options.
An XafApplication can use one or several IObjectSpaceProvider objects at the same time, and you can access this information through the XafApplication.ObjectSpaceProvder or XafApplication.ObjectSpaceProviders properties. Check out these help links to learn more on how to plug in custom IObjectSpaceProvider objects a well.
There are several built-in implementations of the IObjectSpaceProvider and IObjectSpace interfaces in our framework, which are usually specific to a target ORM (Entity Framework or XPO). I suggest you check out the source code of the default framework classes to better understand the role of the IObjectSpaceProvider:
...\DevExpress.ExpressApp.Xpo\XPObjectSpaceProvider.cs
...\DevExpress.ExpressApp.EF\EFObjectSpaceProvider.cs
Typical customization considerations
You may want to provide a fully custom IObjectSpaceProvider implementation or inherit from the built-in implementors when you want to customize how data access is performed for a chosen ORM.
Below is a list of typical scenarios where a custom IObjectSpaceProvider may be required:
1. How to use XPO caching in XAF
2. How to prevent altering the legacy database schema when creating an XAF application
3. How to connect to remote data store and configure WCF end point programmatically
4. How do I change the default schema in the database
5. How to use a custom ObjectSpace throughout the application by handling the CreateCustomObjectSpaceProvider event?
In most cases, it is not required to implement the IObjectSpaceProvider interface from scratch since you can inherit from existing implementors or customize/just their parts.
XPO-specific customizations
1. Implementing IXpoDataStoreProvider
For instance, in XPO one of such replaceable parts is the IXpoDataStoreProvider interface, which enables you to provide a custom or configured IDataStore object, which is used for underlying data access with this ORM:
[C#]publicinterfaceIXpoDataStoreProvider{IDataStoreCreateWorkingStore(outIDisposable[]disposableObjects);IDataStoreCreateUpdatingStore(outIDisposable[]disposableObjects);stringConnectionString{get;}}
In its turn, XAF provides several ready to use implementations of this interface for most popular scenarios:
1. ConnectionDataStoreProvider - can provide IDataStore by the IDbConnection object;
2. ConnectionStringDataStoreProvider - can provide IDataStore by just connecting string information;
3. MemoryDataStoreProvider - DataSet based in-memory IDataStore providers.
Technically, such an IXpoDataStoreProvider part is passed into the XPObjectSpaceProvider constructor as a parameter, which means that you can just customize it instead of re-implementing the whole XPObjectSpaceProvider logic.
Refer to the ...\DevExpress.ExpressApp.Xpo\XPObjectSpaceProvider.cs file within the XAF source code to better understand the role of this part.
2. Overriding XPO connection or database providers
To learn more on this approach, check out the Database Systems Supported by XPO help topic and How to create a custom XPO connection provider and then use it in an XAF application article in particular.
To learn more on customizing data access settings for XPO, please refer to the corresponding product documentation: Data Access Layer.