Skip to main content
A newer version of this page is available. .

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.v21.2.dll

NuGet Package: DevExpress.Wpf.Core

Declaration

public class UnboundDataSource :
    SimpleDataSourceBase

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:

UnboundDataSourceDiagram

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:

UnboundDataSourceProperty

property

Description

UnboundDataSourceProperty.Name

Specifies the name of the property.

UnboundDataSourceProperty.DisplayName

Specifies the display name of the property.

UnboundDataSourceProperty.PropertyType

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" ShowTotalSummary="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" ShowTotalSummary="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.

UnboundDataSourceWPF Sample Application

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:

View Example: How to: Use the UnboundDataSource with the Source Generator

Inheritance

Object
DispatcherObject
DependencyObject
Visual
UIElement
FrameworkElement
Control
DevExpress.Xpf.Core.DXDesignTimeControl
DevExpress.Xpf.Core.DataSources.SimpleDataSourceBase
UnboundDataSource
See Also