0

I used to sort and select data of ObservableCollection object like:

public class MainViewModel : INotifyPropertyChanged
{

    private ObservableCollection<Module> myModulesList;
    private void RefreshModulesByOrder()
    {
        myModulesList = new ObservableCollection<Module>(sdb.GetOrderModules().OrderBy(mod => mod.Address));
        ModulesView = CollectionViewSource.GetDefaultView(myModulesList);
        ModulesView.Filter = obj =>
        {
            var Module = (Module)obj;
            return SelectedProduct != null && SelectedProduct.ModelNumber == Module.ModelNumber;
        };
    }

    private DataSet _ds;
    private void RefreshModules()
    {
        _ds = sdb.GetModules();
        _ds.Tables["Modules"].DefaultView.Sort = "Address";
        ModulesView = new ListCollectionView(_ds.Tables["Modules"].DefaultView)
        {
            Filter = obj =>
            {
                var Module = obj as DataRowView;
                return SelectedProduct != null && SelectedProduct.ModelNumber == Module["ModelNumber"].ToString();
            }
        };
    }

    public ushort[] DatagridToArray()
    {
        return _ds.Tables["Modules"].AsEnumerable().Select(mod => mod.Field<UInt16>("ParamValue")).ToArray();
    }

    private Product selectedProduct;
    public Product SelectedProduct
    { 

        get { return selectedProduct; }
        set
        {
            if (selectedProduct != value)
            {
                selectedProduct = value;
                NotifyPropertyChanged();
                RefreshProductList();
                RefreshModules();
                RefreshCommunication();
            }
        }
    }

}
Lee Barry
  • 37
  • 9
  • Why do you have a DataSet instead of a DataTable. If you have only one DataTable then usually you can use a DataTable instead of a DataSet. To sort a datatabe : dt = dt.AsEnumerable().OrderBy(mod => mod.Address).CopyToDataTable(); The source an destination table must have same schema to work. Your sample code is only selecting one column mod.ParamValue which will not work with a DataTable. – jdweng Jun 20 '17 at 06:30
  • I already have a sorted datatable as **update** above, now I need to get one specific column value by the method `DatagridToArray()`. – Lee Barry Jun 20 '17 at 06:54
  • 1
    var results = _ds.Tables["Modules"].AsEnumerable().Select(x => x.Field("cola")).ToArray(); – jdweng Jun 20 '17 at 07:48
  • Good, Thanks for your answer! – Lee Barry Jun 20 '17 at 07:59
  • This puts all the `ParamValue` in xml file into the Array, which I just want apply to the `SelectedProduct`, do you know how to fix it? – Lee Barry Jun 23 '17 at 05:52
  • The CopyToDataTable clones the schema of the source DataTable so you have all the data. To get only some of the columns you need to either return an object that is not a DataTable or create a new DataTable in the code with less columns. Then the linq needs to have a select statement which extracts from each DataRow the columns needed and put into results (either a new DataTable or a List<>). – jdweng Jun 23 '17 at 06:37
  • the Datatable in the `RefreshModules()` is already selected, I want all the data of thecolumn **ParamValues**, can I directly use it? – Lee Barry Jun 23 '17 at 07:35
  • something like : var Module = obj as DataRowView; var model = SelectedProduct != null && SelectedProduct.ModelNumber == Module["ModelNumber"].ToString(); return model.Select(x => x.RefreshModules).ToList(); – jdweng Jun 23 '17 at 07:55
  • Thanks, as you said, the `_ds` is an instance of DataSet, the **ModulesView** in the `RefreshModules` in a TableView of which column I want to return. Your latest code with syntax I don't know how to fix. – Lee Barry Jun 23 '17 at 09:21
  • Go back to your original code. The use following : var results = ModulesView.Cast().Select(x => x.RefreshModules).ToList(); SelectedProducts (with s) is the type for SelectProduct. – jdweng Jun 23 '17 at 09:50
  • Sorry but how should I declare `SelectedProducts`? My `SelectedProduct` is a method which looks like above. – Lee Barry Jun 23 '17 at 10:21
  • Should be the class name Product : var results = ModulesView.Cast().Select(x => x.RefreshModules).ToList(); – jdweng Jun 23 '17 at 11:25
  • @jdweng Sorry for replying late. Because of my inarticulate words, the `RefreshModules` is not included in the Class `Product` but in the `MainViewModule` as I updated the full structure, could you please tell me how to fix the error? Thanks a lot! – Lee Barry Jun 26 '17 at 02:12

2 Answers2

1

The code contains lots of error. Got rid of all compiler errors, but there is lots of missing code. See : Implementing INotifyPropertyChanged - does a better way exist?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Windows.Data;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
    public class MainViewModel :  INotifyPropertyChanged
    {

        public static Product selectedProduct;
        static DataSet _ds = null;
        static Module sdb = new Module();
        ObservableCollection<Module> myModulesList { get; set; }
        static ICollectionView ModulesView = null;

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            //see : https://stackoverflow.com/questions/1315621/implementing-inotifypropertychanged-does-a-better-way-exist

        }
        private static void NotifyPropertyChanged(Product product)
        {
        }
        private void RefreshModulesByOrder()
        {

            myModulesList = new ObservableCollection<Module>(sdb.GetOrderModules().OrderBy(mod => mod.Address));
            ModulesView = CollectionViewSource.GetDefaultView(myModulesList);
            ModulesView.Filter = obj =>
            {
                var Module = (Module)obj;
                return selectedProduct != null && selectedProduct.ModelNumber == Module.ModelNumber;
            };
        }

        private static Product RefreshModules()
        {
            _ds = sdb.GetModules();
            _ds.Tables["Modules"].DefaultView.Sort = "Address";
            ModulesView = new ListCollectionView(_ds.Tables["Modules"].DefaultView)
            {
                Filter = obj =>
                {
                    var Module = obj as DataRowView;
                    return selectedProduct != null && selectedProduct.ModelNumber == (int)Module["ModelNumber"];
                }
            };
            return null;
        }

        public ushort[] DatagridToArray()
        {
            return _ds.Tables["Modules"].AsEnumerable().Select(mod => mod.Field<UInt16>("ParamValue")).ToArray();
        }
        public static void RefreshProductList()
        {
        }
        public static void RefreshCommunication()
        {
        }
        public class Product
        {
            public int ModelNumber { get; set; }
            public Product SelectedProduct
            {

                get { return selectedProduct; }
                set
                {
                    if (selectedProduct != value)
                    {
                        selectedProduct = value;
                        NotifyPropertyChanged(this);
                        RefreshProductList();
                        RefreshModules();
                        RefreshCommunication();
                    }
                }
            }
        }
        public class Module
        {
            public int ModelNumber { get; set; }
            public int Address { get; set; }
            public DataSet GetModules()
            {
                return new DataSet();
            }
            public List<Module> GetOrderModules()
            {
                return new List<Module>();
            }
        }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Sorry, I did not put all my code, what I am trying to ask is how to make your code `var results = ModulesView.Cast().Select(x => x.RefreshModules).ToList();` correct? In my code, how should I make `DatagridToArray()` return to the array by selected instead of all modules? – Lee Barry Jun 26 '17 at 03:30
  • I can't answer that question. I do not know the relationship between Product and Module. Can you cast Module to Product? I would think that Product is a property of a Module and not equivalent to a Module. I think Product is a row of one of the tables inside the dataset of the module. – jdweng Jun 26 '17 at 03:57
0

This works:

registerArray = _ds.Tables["Modules"].AsEnumerable().OrderBy(mod => mod.Field<UInt32>("Address")).Select(mod => mod.Field<UInt16>("ParamValue")).ToArray();
Lee Barry
  • 37
  • 9