WPF Data Binding details

Source: Internet
Author: User

Windows Presentation Foundation (WPF) Data Binding provides an easy and consistent way for applications to display and interact with data. Elements can be bound to data from various data sources in the form of Common Language Runtime Library (CLR) objects and XML. ContentControl (such as Button) and ItemsControl (such as ListBox and ListView) have built-in functions, so that a single data item or data item set can be flexibly set styles. The sorting, filtering, and grouping views can be generated on top of the data.

The data binding function in WPF has some advantages over traditional models, including supporting various attributes of data binding, flexible data UI representation, and full separation of business logic and UI.

This topic first discusses the basic concepts of WPF data Binding, and then describes the Binding class and usage of other functions of data Binding.

What is data binding?
Data Binding is the process of establishing a connection between the application UI and the business logic. If the binding has correct settings and the data provides correct notifications, the elements bound to the data automatically reflect the changes when the value of the data changes. Data Binding may also mean that if the external representation of the data in the element changes, the basic data can be automatically updated to reflect the changes. For example, if you edit a value in a TextBox element, the basic data value is automatically updated to reflect the change.

A typical usage of data binding is to place server or local configuration data in a form or other UI control. In WPF, this concept is extended, including binding a large number of attributes to various data sources. In WPF, element dependency attributes can be bound to CLR objects (including ADO. NET objects or objects associated with Web Services and Web properties) and XML data.

For data binding examples, take a look at the following application UI from the data binding Demo:


The above is the application UI that displays the list of auction items. This application demonstrates the following features of Data Binding:

The content of ListBox is bound to the set of AuctionItem objects. The AuctionItem object has some attributes, such as Description, StartPrice, StartDate, Category, and SpecialFeatures.

The data displayed in ListBox (AuctionItem object) is templated to display the description and current price of each auction item. This is implemented using a DataTemplate. In addition, the appearance of each item depends on the SpecialFeatures value of the AuctionItem to be displayed. If the SpecialFeatures value of AuctionItem is Color, the item has a blue border. If the value is Highlight, the item has an orange border and an asterisk.

You can use the provided CheckBox to group, filter, or Sort data. In the preceding image, select "Group by category" and "Sort by category and date" CheckBox. You may have noticed that the data is grouped by product category and the category names are sorted alphabetically. These items are also sorted by start date in each category, although it is hard to notice this from the image. This is implemented using the set view.

When you select an item, ContentControl displays the details of the selected item. This is called the master-slave solution.

The StartDate attribute is of the DateTime type, which returns a date, including the time precise to milliseconds. In this application, a custom converter is used to display shorter date strings.

When you click "Add Product", the following form is displayed:


You can edit the fields in the form, preview the product list in the simple preview and detailed Preview pane, and click "submit" to add a new product list. Any existing grouping, filtering, and sorting functions are applied to new projects. In this special case, the items entered in the above image are displayed as the second item in the Computer category.

The verification logic provided in the Start Date TextBox is not displayed in this image. If you enter an invalid date (Invalid format or past date), a red exclamation point next to the ToolTip and TextBox will be used to notify you. The data verification section discusses how to create verification logic.

Before introducing the different functions of Data Binding in detail, we will discuss some basic concepts that are very important to understanding WPF data binding in the next section.

Basic Data Binding concepts

No matter what elements you want to bind, no matter what the characteristics of the data source are, each binding always follows the model shown below:

As shown in, data binding is essentially a bridge between the binding target and the binding source. This figure demonstrates the following basic concepts of WPF Data Binding:

Generally, each binding has four components: bind the target object, target attributes, bind the source, and the path of the value in the binding source to be used. For example, if you want to bind the content of textbox to the name attribute of the employee object, the target object is Textbox, the target attribute is text, and the value to be used is name, the source object is the employee object.

The target attribute must be a dependency attribute. Most uielement attributes are dependency attributes, and most dependency attributes (except read-only attributes) support data binding by default. (Only the dependencyobject type can define the dependency attributes. All uielements are derived from dependencyobject .)

Although it is not pointed out in the figure, it should be noted that binding source objects is not limited to custom CLR objects. WPF Data Binding supports CLR objects and XML data. For example, the binding source can be a uielement, any list object, CLR object associated with ADO. NET data or Web Services, or xmlnode containing XML data.

When reading other sdks topics, remember that when you create a binding, you bind the binding target to the binding source. For example, if you want to bind data to display some basic XML data in a ListBox, You can bind the ListBox to the XML data.

To create a binding, use the binding object. The rest of this topic discusses many concepts related to the binding object and some attributes and usage of the object.

Data Flow Direction
As described above and the middle arrow show, the bound data stream can flow from the data destination to the data source (for example, the source value changes when the user edits the textbox value) and/or (if the binding source provides the correct notification) from the binding source to the binding target (for example, the textbox content will be updated as the binding source changes ).

You may want the application to allow users to change the data and transmit the data back to the source object. Alternatively, you may not want to allow users to update source data. You can control this by setting the mode attribute of the binding object. Demonstrate different types of data streams:

One-way binding will automatically update the target attribute because of changes to the source attribute, but changes to the target attribute will not be transmitted back-to-source attribute. This binding type applies when the bound control is an implicit read-only control. For example, you may be bound to a source such as an auto-recorded stock market, or the target property does not have a control interface for modification (such as the background color of table data binding ). If you do not need to monitor changes to the target attributes, use the oneway binding mode to avoid system overhead in the twoway binding mode.

Because twoway is bound, changes to the source attribute will automatically update the target attribute, and changes to the target attribute will also automatically update the source attribute. This binding type applies to editable forms or other fully Interactive UI schemes. Most attributes are bound to one way by default, but some dependency attributes (usually the attributes of user-editable controls, such as the text attribute of textbox and the ischecked attribute of checkbox) are bound to twoway by default. One programming method for determining whether the Dependency Property is one-way binding or two-way binding by default is to use getmetadata to obtain the property metadata of the property, and then check the Boolean value of the bindstwowaybydefault property.

Onewaytosource is opposite to oneway binding; It updates the source attribute when the target attribute is changed. An example scheme is that you only need to re-calculate the source value from the UI.

The OneTime binding is not shown in the figure. This binding will cause the source attribute to initialize the target attribute, but will not spread subsequent changes. This means that if the data context is changed or the object in the data context is changed, the change is reflected in the target attribute. This binding type is applicable if the snapshot of the data you are using is suitable for use, or the data is static. If you want to use a value in the source attribute to initialize the target attribute without knowing the data context, you can also use this binding type. This binding type is essentially a simplified form of OneWay binding, providing better performance without changing the source value.

Note that to detect source changes (applicable to OneWay and TwoWay binding), the source must implement an appropriate property change notification mechanism (such as INotifyPropertyChanged ).

Reasons for triggering source update
TwoWay or OneWayToSource is bound to listen for changes to the target attribute, and these changes are propagated back to the source. This is called an update source. For example, you can edit the text in the text box to change the base source value. As described in the previous section, the direction of the data stream is determined by the value of the bound Mode attribute.

However, will the source value be updated when you edit the text, or will it be updated after you finish editing the text and remove the mouse pointer from the text box? The bound UpdateSourceTrigger attribute determines the cause of trigger source update. The point on the right arrow shows the role of the UpdateSourceTrigger attribute:

If the UpdateSourceTrigger value is PropertyChanged, the value pointed to by the right arrow bound to TwoWay or OneWayToSource is updated immediately when the target property is changed. However, if the UpdateSourceTrigger value is LostFocus, the value is updated only when the target attribute loses focus.

Similar to the Mode attribute, different dependency attributes have different default UpdateSourceTrigger values. The default values of most dependency properties are PropertyChanged, and the default value of Text properties is LostFocus. This means that the source update usually happens as long as the target property is changed, which is useful for CheckBox and other simple controls. However, text fields are updated after each key-click operation, which reduces the performance. You do not have the opportunity to use the backspace key to modify the typing error before submitting a new value. This is why the default value of the Text attribute is LostFocus rather than PropertyChanged.

The following table uses TextBox as an example to provide an example of each UpdateSourceTrigger value:


Create binding

Some concepts discussed in the previous sections can be summarized as follows: Binding objects are used to establish Binding. Each Binding usually has four components: the path for binding the target, target attribute, source, and source value to be used. This section describes how to set binding.

See the following example. The bound source object is a class named MyData, which is defined in the SDKSample namespace. For demonstration purposes, the MyData class has a string attribute named ColorName, and the value of this attribute is set to "Red ". Therefore, this example generates a button with a red background.


If this example is applied to the basic graph, the generated graph is as follows. This is a OneWay binding, because the Background attribute supports OneWay binding by default.


You may wonder why, even if the ColorName attribute is a type string and the Background attribute is of the Brush type. This is because of the default type conversion. This type conversion is discussed in the data conversion section.

Bind Source
Note that in the previous example, the binding source is specified by setting the datacontext attribute on the dockpanel element. The button then inherits the datacontext value from the dockpanel (which is its parent element. Repeat here that binding the source object is one of the four required components bound. Therefore, if you do not specify the source object to be bound, the binding will not work.

You can specify the bound source object in multiple ways. When you bind multiple attributes to the same source, you can use the datacontext attribute on the parent element. However, it may be more appropriate to specify the binding source on each binding declaration. In the previous example, you can specify the binding source by directly setting the source attribute on the button binding declaration instead of using the datacontext attribute, as shown in the following example:


In addition to setting the datacontext attribute directly on the element and inheriting the datacontext value from the upper-level (for example, the button in the first example) by setting the source attribute on the binding, You can explicitly specify the binding source (such as the button in the last example). You can also use the elementname attribute or relativesource attribute to specify the binding source. The elementname attribute is useful when other elements are bound to an application (for example, when the slider is used to adjust the width of the button. The relativesource attribute is useful when binding is specified in controltemplate or style.

Path of the specified value
If the binding source is an object, you can use the path attribute to specify the value to be used for binding. If you want to bind XML data, you can use the XPath attribute to specify this value. In some cases, you can use the path attribute even if the data is XML. For example, if you want to access the name attribute of the returned xmlnode (as the result of the XPath query), you should use the path attribute and the XPath attribute.

Note that although we have stressed that the path of the value to be used is one of the four required components to be bound, to bind to the entire object, the value to be used will be the same as the bound source object. In these cases, it is appropriate to not specify the path. See the following example:


The above example uses the null Binding Syntax: {Binding }. In this case, ListBox inherits DataContext from the parent DockPanel element (not shown in this example ). If no path is specified, the entire object is bound by default. In other words, in this example, the path has been omitted because the ItemsSource attribute must be bound to the entire object.

In addition to binding to a collection, you can also use this solution when you want to bind to the entire object instead of only a single attribute of the object. For example, if the source object is a type string and you only want to bind it to the string itself. Another common case is that you want to bind an element to an object with multiple attributes.

Note that you may need to apply custom logic to make data meaningful to your binding target attributes. The custom logic format can be a custom converter (if the default type conversion does not exist ).

Binding and bindingexpression
The BindingExpression class is useful before you describe other functions and usage of Data Binding in detail. As described in the previous sections, the Binding class is a high-level class used to bind declarations. The Binding class provides many attributes that you can use to specify Binding features. The related class BindingExpression is the basic object for maintaining the connection between the source and target. A binding includes all the information that can be shared among multiple binding expressions. BindingExpression is an instance expression that cannot be shared. It contains all instance information about Binding.

For example, see the following example. myDataObject is an instance of the MyData class, myBinding is the source Binding object, and MyData is a defined class that contains a string attribute named MyDataProperty. In this example, the text content of mytext (TextBlock instance) is bound to MyDataProperty.



You can use the same myBinding object to create other bindings. For example, you can use the myBinding object to bind the text content of the check box to MyDataProperty. In this case, two BindingExpression instances share the myBinding object.

You can call the return value of GetBindingExpression to obtain the BindingExpression object. The following topics demonstrate some usage of the BindingExpression class:

How to: Get the bound object from the bound object property

How to: control the time when the text in the text box is updated to the source

Data Conversion
In the preceding example, the button is Red because its Background property is bound to a string property with a value of "Red. This can be done because a type converter is provided on the Brush type to convert the string value to the Brush.

To add this information to the graph in the create binding section, the diagram is as follows:


However, what should I do if the bound source object has a Color attribute instead of a type string? In this case, you must first convert the Color attribute value to the value accepted by the Background attribute to make the binding work normally. You need to create a custom Converter by implementing the IValueConverter interface, as shown in the following example:


The custom converter is used instead of the default conversion. The diagram is as follows:


Repeat here, because the type converter is provided in the type to be bound, you can use the default conversion. This behavior depends on the type converter available in the target. If you are not sure, create your own converter.

The following provides some typical solutions. In these solutions, it is very meaningful to implement a data converter:

Data should be displayed in different ways according to the region. For example, you may need to implement a currency converter or calendar date/time converter based on the values or standards used in a specific region.

The data used does not necessarily change the text value of the attribute, but changes another value (the source of the image or the color or style of the text ). In this case, you can use the converter by binding attributes that may not be suitable for conversion (for example, binding text fields to the Background attribute of table cells.

Bind multiple attributes of multiple controls or controls to the same data. In this case, the primary binding may only display text, while other binding processes specific display issues, but still uses the same binding as the source information.

So far, we have not discussed MultiBinding (its target property has a binding set ). For MultiBinding, you can use custom IMultiValueConverter to generate the final value from the bound value. For example, you can calculate the color from values in red, blue, and green. These values may come from the same or different bound source object values.

Bind to collection

Binding a source object can be regarded as a single object whose attributes contain data, or a data set of a multi-state object that is usually combined (such as querying the database results ). So far, we have discussed binding to a single object, but binding to a data set is a common solution. For example, a common solution is to use ItemsControl (such as ListBox, ListView, or TreeView) to display data sets. For example, what is data binding? As shown in the Application Section.

Fortunately, the basic graph still applies. If you want to bind ItemsControl to a set, the diagram is as follows:


As shown in the preceding figure, to bind ItemsControl to a collection object, use the ItemsSource attribute. You can regard the ItemsSource attribute as the content of ItemsControl. Note that one-way binding is supported by default because the ItemsSource attribute supports one-way binding.

How to implement a set
You can enumerate any set that implements the IEnumerable interface. However, to set dynamic binding so that the insertion or removal operations in the set can automatically update the UI, the set must implement the INotifyCollectionChanged interface. This interface exposes an event. This event should be triggered as long as the basic set is changed.

WPF provides the ObservableCollection <(Of <(T>)> class, which is a built-in implementation Of the data set that exposes the INotifyCollectionChanged interface. Note: to fully support the transfer of data values from the source object to the target, each object in the set that can bind attributes must implement the INotifyPropertyChanged interface.

Before implementing your own collection, consider using ObservableCollection <(Of <(T>) or an existing collection class, such as List <(Of <(T>), Collection <(Of <(T>) and BindingList <(Of <(T>. If you have an advanced solution and want to implement your own set, consider using IList, which provides a non-generic set of objects that can be accessed one by index, thus providing the best performance.

Set View
Once ItemsControl is bound to a data set, you may want to sort, filter, or group the data. To perform this operation, you can use the set view, which is the class that implements the ICollectionView interface.

What is a set view?
The set view can be considered as the layer at the top of the bound source set. You can use it to navigate and display the source set by sorting, filtering, and grouping query, all these operations do not require the basic source set itself. If the source set implements the INotifyCollectionChanged interface, the changes caused by the CollectionChanged event will be propagated to the view.

Because the view does not change the basic source set, each source set can have multiple associated views. For example, you can have a set of Task objects. You can use views to display the same data in different ways. For example, you may want to display tasks sorted by priority on the left side of the page, and tasks grouped by region on the right side of the page.

How to Create a view
One way to create and use a view is to directly instantiate the view object and use it as the binding source. For example, what is data binding? Data Binding demo application demonstrated in section 1. This application binds the ListBox to the closed view of the dataset instead of directly binding it to the data set. The following example is taken from the data binding demo application. The collectionviewsource class is the Extensible Application Markup Language (XAML) proxy of collectionview. In this specific example, the source of the view is bound to the auctionitems set of the current application object (type: observablecollection <(of <(T> )).


The resource listingdataview is subsequently used as the binding source for elements (such as ListBox) in the application:


To create another view for the same set, you can create another collectionviewsource instance and provide it with another X: key name.

Using a view as a binding source is not the only way to create and use a set view. All sets have a default set view. For example, for all sets that implement ienumerable, collectionview is the default view object. Listcollectionview is the default view object that implements the ilist set, while bindinglistcollectionview is the set View class that implements the ibindinglist set. To obtain the default view, use the getdefaultview method.

As mentioned above, the view can apply the sorting order to the set. As in the basic set, data may have or do not have an inherent sequence. The view on the set allows you to apply the sequence or change the default Sequence Based on the comparison conditions you provide. Because this is a client-based data view, a common situation is that you may want to sort data in multiple columns based on the values of the columns. Using views, you can apply user-driven sorting without making any changes to the basic set, or even querying the set content again.

The following example shows what is data binding? The sorting logic of the "Sort by category and date" (sorted by category and date) CheckBox in the application UI in this section:


The view can also apply a filter to a set. This means that this view is only used to display a subset of the entire set even if an item may exist in the set. You can filter data based on conditions. For example, in what is data binding? In the way applications work in this section, the "Show only bargains" CheckBox contains the logic to filter items with a transaction price of $25 or higher. Run the following code to set ShowOnlyBargainsFilter to the Filter event handler when you select this CheckBox:


The ShowOnlyBargainsFilter event handler has the following implementation:


If you directly use a CollectionView class instead of CollectionViewSource, you should use the Filter attribute to specify the callback.

View supports grouping, which allows you to partition a set in the set view into a logical group. These groups can be explicit, and users can provide a group list or implicitly. The groups are dynamically generated based on data.

The following example demonstrates the logic of "Group by category" (grouped by category) CheckBox:


Current record pointer
The view also supports the concept of the current item. You can navigate between objects in the set view. During navigation, you are moving the record pointer, which can be used to retrieve objects that exist in a specific position in the set.

Note that the movement of the current record pointer and any sorting or filtering applied to the set will affect each other. Sorting retains the current record pointer on the last selected record, but the set view is now restructured around this pointer. (The selected record may have previously started with the list, but the selected record may be somewhere in the middle .) If the selected content is retained in the view after filtering, the filtering operation retains the selected records. Otherwise, the current record pointer is set to the first record in the filtered set view.

Master-slave binding Scheme
The concept of the current item is not only used for item navigation in the set, but also for the master-slave binding scheme. What is data binding? Application UI in. In this application, the selected content of ListBox determines the content displayed in ContentControl. In other words, when a ListBox item is selected, ContentControl displays the details of the selected item.

By binding two or more controls to the same view, you can easily implement the master-slave solution. The following is an example of data binding demonstration. What is data binding? The tag of ListBox and ContentControl displayed in the application UI:


Note that both controls are bound to the same source, that is, listingDataView static resources (see how to create the definition of this resource in the view section ). This can be done because when a single instance object (ContentControl in this example) is bound to a set view, the object is automatically bound to the CurrentItem of the view. Note that the CollectionViewSource object automatically synchronizes the currency with the selected content. If the list control is not bound to the CollectionViewSource object as in the example, you need to set its IsSynchronizedWithCurrentItem attribute to true to achieve this purpose.

You may have noticed that the preceding example uses a template. In fact, if the template is not used (the template explicitly used by ContentControl and the template implicitly used by ListBox), the data will not be displayed as expected. Now, we will introduce the data templatification in the next section.

Templated data
If no data template is used, what is data binding? The application UI in this section is as follows:


As shown in the example in the previous section, both the ListBox control and contentcontrol are bound to the entire set object of the auctionitem (more specifically, the view bound to the set object ). Without specific instructions on how to display a data set, ListBox displays the string representation of each object in the basic set, and contentcontrol displays the string representation of the bound object.

To resolve this issue, the application should define the ememplate. As shown in the preceding example, contentcontrol explicitly uses detailsproductlistingtemplate datatemplate. When the auctionitem object in the set is displayed, The ListBox control implicitly uses the following datatemplate:

Using these two plate emplates, what is the data binding UI? . As shown in the screen snapshot, in addition to placing data in the control, datatemplate can also define compelling visual effects for data. For example, if datatrigger is used in the datatemplate, The auctionitem with the specialfeatures value of highlight is displayed as an orange border and an asterisk.

Data Verification

Most applications that accept user input must have verification logic to ensure that the user inputs the required information. Verification checks can be based on type, range, format, or other application-specific requirements. This section describes how data verification works in WPF.

Associate verification rules with bindings
The WPF data binding model can be used to associate validationrules with the binding object. For example, what is data binding? Add product listing (add product list) "Start price" (start price) textbox's XAML in this section:


The ValidationRules attribute uses the set of ValidationRule objects. Predictionvalidationrule is a built-in ValidationRule used to check exceptions thrown during update of bound source attributes. In this specific example, the binding source attribute is StartPrice (belongs to the integer type), and the target attribute is TextBox. Text. When the value entered by the user cannot be converted to an integer, an exception is thrown, which causes the binding to be marked as invalid.

You can also create your own validation rules by deriving from the ValidationRule class and implementing the Validate method. The following example shows what is data binding? In this section, Add Product Listing (Add Product list) "Start Date" (Start Date) Rules used by TextBox:


StartDateEntryForm TextBox uses this FutureDateRule, as shown in the following example:


Note that because the UpdateSourceTrigger value is PropertyChanged, the binding engine updates the source value every time you press the key, this means that the engine will also check each rule in the ValidationRules set each time it is clicked. We will have a more in-depth discussion in the "verification process" section.

Provide visual feedback
If the value entered by the user is invalid, you may want to provide some error feedback on the application UI. One way to provide such feedback is to set the additional property of Validation...:. ErrorTemplate to custom ControlTemplate. As shown in the previous section, StartDateEntryForm TextBox uses an ErrorTemplate named validationTemplate. The following example shows the definition of validationTemplate:


The AdornedElementPlaceholder element specifies the position of the control to be decorated.

In addition, you may also use ToolTip to Display error messages. StartDateEntryForm and StartPriceEntryForm TextBox both use the style textStyleTextBox, which creates a ToolTip that displays the error message. The following example shows the definition of textStyleTextBox. If one or more attributes of the element to be bound have an error, the added attribute Validation. HasError is true.


With the custom ErrorTemplate and ToolTip, The StartDateEntryForm TextBox is shown as follows when a verification error occurs:


If your Binding has an association verification rule, but you have not specified an ErrorTemplate on the Binding control, the default ErrorTemplate will be used to notify the user when a verification error occurs. The default ErrorTemplate is a control template that defines the red border in the modifier layer. The default ErrorTemplate and ToolTip are used. The UI of StartPriceEntryForm TextBox is shown as follows when a verification error occurs:


For examples of how to provide logic to verify all controls in the dialog box, see the "Custom dialog box" section in the dialog box overview.

Verification process
Because data verification is related to updates from the target to the source, it applies only to TwoWay and OneWayToSource bindings. Verification occurs every time the input value is transmitted to the bound source attribute. Repeat here. The cause of source update depends on the value of the UpdateSourceTrigger attribute, as described in the reason for source update.

The following illustration provides a visual representation of the locations suitable for verification during data binding:


As shown in, the verification occurs during the value transfer from the target to the source before the converter is called. The verification process is described below, as marked in the above diagram:

When the value is transmitted from the target attribute to the source attribute, the Data Binding engine first removes any validationerror that may have been added to the validation. Errors additional attribute of the binding element. Then, the Data Binding engine checks whether a custom validationrule is defined for the binding. If yes, it calls the validate Method on each validationrule, until one rule fails or all rules pass.

If a custom rule fails, the binding engine creates a validationerror object and adds the object to the validation. Errors set of the binding element. If validation. errors is not empty, the additional attribute of validation. haserror of the element is set to true. In addition, if the notifyonvalidationerror attribute of binding is set to true, the binding engine will trigger an additional event of validation. Error on this element.

If all rules pass, the binding engine calls the converter (if any ).

If the converter passes, the binding engine calls the setter of the source attribute.

If you bind the exceptionvalidationrule associated with it, and an exception is thrown in Step 4, the binding engine checks whether updatesourceexceptionfilter exists. You can use the updatesourceexceptionfilter callback to provide a Custom Handler for exception handling. If you do not specify updatesourceexceptionfilter for binding, the binding engine creates a validationerror for the exception and adds it to the validation. Errors set of the binding element.

It should also be noted that the valid value transfer operation in any direction (from the target to the source or from the source to the target) will clear the validation. Errors additional attribute.

Debugging Mechanism
You can set the additional property presentationtracesources...:. tracelevel on the bound object to receive information about the status of a specific binding.


From: http://blog.163.com/bruce_lee04/blog/static/45755321201008102135814/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.