views:

521

answers:

3

Hi a quick question really in WPF.

Does anyone know how i can bind a combo box that will sit in a grid to a dataset that i have.

The dataset contains several columns and numerious rows but i want to take one of the columns, lets say ProcessID and just show that in the comobo box.

Has anyone done this before or know how it can be done in WPF.

Thanks Iffy.

A: 

You should use LINQ to SQL,ADO.Net, or entity framework to extract data from database, you can't bind combobox with database table, but whit data in the memory

ArsenMkrt
A: 

To do it programmatically, here's a generic function i have for it:

    /// <summary>
    /// Thread safe method for databinding the specified ComboBox with the specified data.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="ctrl">The Combo to be databound.</param>
    /// <param name="datasource">The data to be bound to the Combo.</param>
    /// <param name="displayPath">The name of the property in the data objects that should be used for the display value.</param>
    /// <param name="valuePath">The name of the property in the data objects that should be used for the value.</param>
    /// <remarks>
    /// This function was written as generic so that it doesn't matter what types the IEnumerabe datasource is, it can handle them all.
    /// </remarks>
    private void UpdateComboDataSource<T>(ComboBox ctrl, IEnumerable<T> datasource, string displayPath, string valuePath)
    {
        if (ctrl == null)
            throw new ArgumentNullException("Control to be bound must not be null");

        //check if we are on the control's UI thread:
        if (ctrl.Dispatcher.CheckAccess())
        {
            //we have full access to the control, no threading issues, so let's rip it up and databind it
            datasource = datasource.OrderBy(x => x);
            if (displayPath != null && ctrl.DisplayMemberPath == null)
                ctrl.DisplayMemberPath = displayPath;
            if (valuePath != null && ctrl.SelectedValuePath == null)
                ctrl.SelectedValuePath = valuePath;

            ctrl.ItemsSource = datasource;

            //be nice to the user, if there is only one item then automatically select it
            ctrl.SelectedIndex = datasource.Count() == 1 ? 0 : -1;
        }
        else
        {
            //we don't have full access to the control because we are running on a different thread, so 
            //we need to marshal a call to this function from the control's UI thread
            UpdateComboDataSourceDelegate<T> del = new UpdateComboDataSourceDelegate<T>(this.UpdateComboDataSource);
            ctrl.Dispatcher.BeginInvoke(del, ctrl, datasource, displayPath, valuePath);
        }
    }

    private delegate void UpdateComboDataSourceDelegate<T>(ComboBox ctrl, IEnumerable<T> dataSource, string displayPath, string valuePath);

The comments tell you everything you need to know. It could also be done programmatically by creating a Binding between the control's ItemSource property and a public property on your page - this is the same way as it is done declaratively (there must be a billion examples of that out there though, so i won't show it here).

slugster
Thanks for your help. I really appreciate it. :)
Iffy
+1  A: 

Assuming this is a capital D DataSet that you can expose to XAML as a property on a DataContext object (showing the "Description" column for each row in the "LookupTable" table):

    <ComboBox ItemsSource="{Binding Path=MyDataSetExposedAsAProperty.Tables[LookupTable].Rows}"
DisplayMemberPath=".[Description]"/>
John Bowen