DataGrid's cannot use DataView as ItemsSource in 16299

7 posts, 0 answers
  1. SkyBlue
    SkyBlue avatar
    7 posts
    Member since:
    Aug 2016

    Posted 25 Nov 2017 Link to this post

    I create a 16299 UWP project and use DateView as ItemsSource for DataGrid. But the UI cannot show the data.

    <my:RadDataGrid x:Name="dataGrid" AutoGenerateColumns="False" >
     </my:RadDataGrid>
    public sealed partial class MainPage : Page
        {
            private ObservableCollection<Dictionary<string, string>> items = new ObservableCollection<Dictionary<string, string>>();
     
            public ObservableCollection<Dictionary<string, string>> ItemDictionary
            {
                get
                {
                    return items;
                }
                set
                {
                    items = value;
                }
            }
     
            public DataTable Items { get; set; }
            public MainPage()
            {
                this.InitializeComponent();
                CreateItems();
                CreateTable();
            }
     
            private void CreateItems()
            {
                for (int i = 0; i < 5; i++)
                {
                    Dictionary<string, string> row = new Dictionary<string, string>();
                    row["A"] = "A" + i.ToString();
                    row["B"] = "B" + i.ToString();
                    row["C"] = "C" + i.ToString();
     
                    ItemDictionary.Add(row);
     
                }
            }
     
            private void CreateTable()
            {
                Items = new DataTable();
     
                if (ItemDictionary.Count == 0) return;
     
                foreach (KeyValuePair<string, string> entry in ItemDictionary[0])
                {
                    DataColumn column = new DataColumn(entry.Key);
                    Items.Columns.Add(column);
                    Telerik.UI.Xaml.Controls.Grid.DataGridTextColumn dgc = new Telerik.UI.Xaml.Controls.Grid.DataGridTextColumn();
                    dgc.Name = entry.Key;
                    dgc.Header = entry.Key;
                    dgc.PropertyName = entry.Key;
                    dataGrid.Columns.Add(dgc);
                }
     
                foreach (Dictionary<string, string> rowEntry in ItemDictionary)
                {
                    DataRow row = Items.NewRow();
                    int col = 0;
                    foreach (KeyValuePair<string, string> entry in rowEntry)
                    {
                        row[entry.Key] = entry.Value;
                    }
                    Items.Rows.Add(row);
                }
                DataView dv = Items.DefaultView;
                dataGrid.ItemsSource = dv;
            }
        }
  2. Lance | Principal TSE
    Admin
    Lance | Principal TSE avatar
    1043 posts

    Posted 27 Nov 2017 Link to this post

    Hello Mo,

    Please this answer from Nasko, it has a link to a video and sample code on how to accomplish your goal.

    The key takeaway is that you do not directly set a DataView or DataTable (this is not supported), instead you use ToList() to create an IEnumerable that can then be bound to the DataGrid.


    Note: I see you have opened an identical forum post, I will respond there with a link back to this post.

    Regards,
    Lance | Tech Support Engineer, Sr.
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. Chad
    Chad avatar
    3 posts
    Member since:
    Jul 2019

    Posted 16 Jul in reply to Lance | Principal TSE Link to this post

    This is really annoying.  You basically have NO way of supporting basic dynamic data binding without an explicit view model.  Why?  Seriously, we ALL know that there are many cases where we will never know the data we're dealing with at compile time.  Data can come dynamically from JSON, XML, and SQL.  Without the ability to bind a grid to commonly used structures (like a Newtonsoft JSON, .NET DataTable or Dictionary), this grid has VERY limited use for apps that use modern ways of gathering and managing data (like JSON-Schema).  Making a little "model" with a product number and name in it for binding is just toy code that exists in your heads.  Serious apps go way beyond this.  For the money you charge for your products, aside from nice colors and images, the lack of critical functionality leaves me floored. This control's performance (or lack thereof) is unacceptable for commercial use in powerful data-collecting apps.
  4. Lance | Principal TSE
    Admin
    Lance | Principal TSE avatar
    1043 posts

    Posted 17 Jul Link to this post

    Hello Chad,

    Telerik UI for UWP is free and open source, you can find it here: https://github.com/telerik/UI-For-UWP.

    I was not able to find any feature requests for the UWP DataGrid to move away from IEnumerable in either the GitHub Issues list or in the official UI for UWP Feedback Portal. This is the main reason I suspect it has not been implemented in UWP, there just hasn't been much demand.

    That being said, I do agree this would be a very useful feature for a UWP application and I recommend you open a Feature Request for DataTable, dynamic or ExpandoObject support. Go here and click the "Feature Request" button.


    > Note that other data source types are supported by the Telerik UI for WPF controls data grid, see RadGridView documentation.

    Options to move forward


    Option 1 - Fork the repo and add support for what you need

    This is not usually an option for most people. However, if you are comfortable with building from source, you can fork the repo and add support for exactly what you need. Then, use that version in your projects instead of the Telerik NuGet packages.

    Option 2 - Use List<dynamic> (most feasible option)

    One thing you can try is to use the dynamic object, that way you don't need a predetermined class to deserialize the JSON into. Here's a prototype example of what I mean:

    public partial class MainPage : Page
    {
        private dynamic source;
      
        public MainPage()
        {
            InitializeComponent();
      
            // Instantiate the dynamic as an IEnumerable
            source = new List<dynamic>();
      
            // Example Dynamic data
            dynamic employee1 = new ExpandoObject();
            employee1.Name = "John Smith";
            employee1.Position = "Engineer";
            employee1.Sales = 20;
            source.Add(employee1);
      
            dynamic employee2 = new ExpandoObject();
            employee2.Name = "Michael";
            employee2.Position = "Pilot";
            employee2.Sales = 9;
            source.Add(employee2);
      
      
            // 1 - Create your columns and add them to the DataGrid
            DataGrid.Columns.Add(new DataGridTextColumn
            {
                Header = "Name",
                PropertyName = "Name"
            });
      
            DataGrid.Columns.Add(new DataGridTextColumn
            {
                Header = "Position",
                PropertyName = "Position"
            });
      
            DataGrid.Columns.Add(new DataGridNumericalColumn()
            {
                Header = "Sales",
                PropertyName = "Sales"
            });
      
            // 2 - Set the ItemsSource to your dynamic data
            DataGrid.ItemsSource = source;
        }
    }

    Though in that example I hard code the property names when creating the columns, you can just use reflection to the get property name out of the ExpandoObejct (or your preferred dynamic object).


    Feedback 

    Please don't hesitate to leave feedback about the performance issues, missing features and other problems you mentioned where the developers can see and act on it. The UI for UWP Feedback Portal is the best place because it ties directly into TFS work items, but GitHub Issues are good too. 

    Thank you for your understanding and for taking the time to read this full message.

    Regards,
    Lance | Technical Support Engineer, Principal
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items

  5. Chad
    Chad avatar
    3 posts
    Member since:
    Jul 2019

    Posted 01 Aug in reply to Lance | Principal TSE Link to this post

    Again, your example requires that you know beforehand what the ExpandoObject contains - it defeats the purpose altogether.  ExpandoObject discovery is nonexistent - and that's why your example (another imaginary toy example) didn't show how it's done.  The day of my original post, I set out to solve this problem... and I did.  I'd be willing to share my approach with anyone who requests it.  Since it's beyond the scope of my current tasks, I have not provided a repository for this; maybe when I have time, I'll eventually do so.

    Ultimately, I ended up building a solution based on inheriting from DynamicObject.  My class keeps track of fields and their types in a list of property descriptors (since you need to have access the property/field types to get the grid header and other features to work properly in your data grid control).  The class type allows you to then convert a list of these objects into a list of Expando objects that then can be bound to the grid.  I added the ability to go from JSONschema to DynamicObject (a super class) to ExpandoObject, and also to and from SQLite (solution aimed at Xamarin mobile apps). I placed this inside of a .NET Standard library so that it works for Android, iOS, and Windows.  This solution is fairly quick, flexible and extremely dynamic

    However, I lost many hours having to home-grow a solution for a common scenario that's been around fro a VERY long time.  Again, data grids have been a basic UI need for software developers for decades now.  Yet no one seems to understand that - or it seems we're always starting from scratch and reinventing the wheel every time we make a slight platform jump or change.  Why, I don't know... but it gets tiresome.   Xamarin Forms has been particularly counterproductive over the last few years - gaping holes where even basic functionality isn't provided... I've had to do so much in the way of custom renders to the point where I wonder why Xamarin Forms was ever released.  It's a nice concept, it it has potential - but the real point of it should be to allow rapid app development with quality UI abilities out of the box.  That has not been the case.  It's like pulling teeth every inch of the way.  Companies that support Xamarin forms with third party controls have only been slightly better.  Xamarin forms is great if you're only supporting one platform - but if you truly want to create a cross-platform code base for your products, be prepared to do a LOT of work.  Before MS took it over, Xamarin cost me $2,500.00/yr - and Xamarin Forms wasn't even half-baked at the time.

  6. Chad
    Chad avatar
    3 posts
    Member since:
    Jul 2019

    Posted 01 Aug in reply to Lance | Principal TSE Link to this post

    Just to make it a bit clearer here, this datagrid is part of a suite of Xamarin Forms controls that costs close to $1,000/year.  The UWP code is only one of three platforms (iOS, Android, and Windows) that I'm supporting through Xamarin and Xamarin Forms. While I like the idea of open source, I don't like the idea of actually growing and maintaining it myself - that's why I'm paying for it.  I have other issues to focus on and deal with.  I expect the component writers to reasonably keep up with and maintain their end of the bargain; it's what makes your products and support worth paying for in the first place.

  7. Lance | Principal TSE
    Admin
    Lance | Principal TSE avatar
    1043 posts

    Posted 02 Aug Link to this post

    Hi Chad,

    My apologies for the delay, I wanted to first speak to the product management team and pass on your feedback personally before responding again.

    I do understand your frustration at having to build a conversion system for a feature that you believe should have been already available. I've have discussed why DataView/DataTable/JSON data sources were not implemented and right now it comes back to the fact that there just has not been much demand for it in UWP, thus other higher priority items took precedence.

    That being said, it doesn't mean that is the final answer, it's just the reason for why it's not currently available.  I will have another discussion about it with the development team next week when the lead developer is available. This isn't any sort of promise that the feature request will be approved, but it is the beginning of the conversation of how and if it can be officially added.

    Although you've explained that you've already built out a system for yourself in this app, I've opened a Feature Request so that you can be informed of the progress. It is possible that there are other options than the DataTable to List or ExpandoObject approaches that he can share.

    Feature Request - Add Support For Non-IEnumerable Data Sources

    Please let me know if there is anything else I can assist with in the meantime.

    Regards,
    Lance | Technical Support Engineer, Principal
    Progress Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top