UnboundDataSource Class
A data source used to supply and obtain a typed list of objects to DevExpress controls.
Namespace: DevExpress.Xpf.Core.DataSources
Assembly: DevExpress.Xpf.Core.v24.2.dll
NuGet Package: DevExpress.Wpf.Core
Declaration
Remarks
Use the UnboundDataSource to bind DevExpress controls to a data source when no strongly typed data set is available at compile time.
The following image illustrates the basic functionality of the UnboundDataSource component:
Map the UnboundDataSource to Data
To map the UnboundDataSource
to data, populate the UnboundDataSource.Properties collection with UnboundDataSourceProperty objects. Each UnboundDataSourceProperty object identifies a data source field.
Use the following properties to associate an UnboundDataSourceProperty object with a data source field:
property | Description |
---|---|
Specifies the name of the property. | |
Specifies the display name of the property. | |
Specifies the type of the property. |
The following example demonstrates an UnboundDataSource
with two columns. Users can edit the Numbers column values with the SpinEdit editor.
<Window ...
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid">
<Window.Resources>
<dx:UnboundDataSource x:Key="UnboundDataSource" Count="100">
<dx:UnboundDataSource.Properties>
<dx:UnboundDataSourceProperty DisplayName="ID" Name="Numbers" PropertyType="{x:Type sys:Int32}"/>
<!-- UnboundDataSourceProperty.DisplayName property specifies the default column header -->
<dx:UnboundDataSourceProperty DisplayName="String Values" Name="Strings" PropertyType="{x:Type sys:String}"/>
</dx:UnboundDataSource.Properties>
</dx:UnboundDataSource>
</Window.Resources>
<Grid>
<dxg:GridControl AutoGenerateColumns="AddNew" EnableSmartColumnsGeneration="True" ItemsSource="{Binding Data, Source={StaticResource UnboundDataSource}}">
<!-- UnboundSourceProperty.Name value is used to specify the field name -->
<dxg:GridColumn FieldName="Numbers" Header="ID">
<dxg:GridColumn.EditSettings>
<dxe:SpinEditSettings/>
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
<dxg:GridControl.View>
<dxg:TableView AllowPerPixelScrolling="True"/>
</dxg:GridControl.View>
</dxg:GridControl>
</Grid>
</Window>
Transfer Data Between Client and Source
Handle the following events to transfer data between the client and the data source:
Event | Description |
---|---|
UnboundDataSource.ValueNeeded | Occurs each time an item is pulled from the data source. |
UnboundDataSource.ValuePushed | Occurs each time the modified data is pushed to the data source. |
Note
When a data-aware control is initially populated with data, the UnboundDataSource.ValueNeeded event fires each time a value is pulled from the data source.
For example, if you set the row count to 10 and the UnboundDataSource.Properties collection contains 2 UnboundDataSourceProperty objects, the UnboundDataSource.ValueNeeded event will occur 20 times.
The following example demonstrates the UnboundDataSource
linked to the ViewModel class that contains sample data.
<Window ...
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid">
<Window.Resources>
<dx:UnboundDataSource x:Key="UnboundDataSource" Count="100" ValueNeeded="UnboundDataSource_ValueNeeded" ValuePushed="UnboundDataSource_ValuePushed">
<dx:UnboundDataSource.Properties>
<dx:UnboundDataSourceProperty DisplayName="ID" Name="Numbers" PropertyType="{x:Type sys:Int32}"/>
<dx:UnboundDataSourceProperty DisplayName="String Values" Name="Strings" PropertyType="{x:Type sys:String}"/>
</dx:UnboundDataSource.Properties>
</dx:UnboundDataSource>
</Window.Resources>
<Grid>
<dxg:GridControl AutoGenerateColumns="AddNew" EnableSmartColumnsGeneration="True" ItemsSource="{Binding Data, Source={StaticResource UnboundDataSource}}">
<dxg:GridControl.View>
<dxg:TableView AllowPerPixelScrolling="True"/>
</dxg:GridControl.View>
</dxg:GridControl>
</Grid>
</Window>
public class ViewModel {
//Each data cell is identified by a list index and key value.
//The key is a string that specifies the column name.
public List<Dictionary<string, object>> Data { get; set; }
public ViewModel() {
CreateList();
}
//Populates the list with sample data.
void CreateList() {
Data = new List<Dictionary<string, object>>();
//Creates 1000 rows
for (int i = 0; i < 1000; i++) {
Data.Add(CreateDictionary(i));
}
}
//Each dictionary object is a data row.
//Each dictionary item is a cell value. It stores a string (column name) and a value (cell value).
Dictionary<string,object> CreateDictionary(int i) {
Dictionary<string, object> dict = new Dictionary<string, object>();
//Specifies the value in the "Strings" column
dict.Add("Strings", "Value" + i.ToString());
//Specifies the value in the "Numbers" column
dict.Add("Numbers", i);
return dict;
}
}
public partial class MainWindow : Window {
public MainWindow() {
vm = new ViewModel();
DataContext = vm;
InitializeComponent();
}
//Processes the pull operation
private void UnboundDataSource_ValueNeeded(object sender, DevExpress.Data.UnboundSourceValueNeededEventArgs e) {
var index = e.RowIndex;
if(e.PropertyName == "Strings") {
e.Value = vm.Data[index]["Strings"];
}
if(e.PropertyName == "Numbers") {
e.Value = vm.Data[index]["Numbers"];
}
}
//Processes the push operation
private void UnboundDataSource_ValuePushed(object sender, DevExpress.Data.UnboundSourceValuePushedEventArgs e) {
var index = e.RowIndex;
if(e.PropertyName == "Strings") {
vm.Data[index]["Strings"] = (string)e.Value;
}
if(e.PropertyName == "Numbers") {
vm.Data[index]["Numbers"] = (int)e.Value;
}
}
}
The following image demonstrates the result.
Example: Use the UnboundDataSource with Source Generator
The DevExpress MVVM Framework includes a source generator that produces boilerplate code for your View Models at compile time.
The following example illustrates how to use the UnboundDataSource with the source generator:
Related GitHub Examples
The following code snippet (auto-collected from DevExpress Examples) contains a reference to the UnboundDataSource class.
Note
The algorithm used to collect these code examples remains a work in progress. Accordingly, the links and snippets below may produce inaccurate results. If you encounter an issue with code examples below, please use the feedback form on this page to report the issue.