How to bind a converter

11 posts, 1 answers
  1. Ludovic Gerbault
    Ludovic Gerbault avatar
    226 posts
    Member since:
    Apr 2009

    Posted 21 Aug 2009 Link to this post

    Hello,

    Here's my problem.

    I have a RadGridView that can display any number of columns of any type, depending on which id you give it.

    Some of those columns can have a DateTime type.

    I'd like to format those columns, but I can't find how.

    I though using a DataFormatString, but my columns are dynamic, so it can't be in the xaml part.
    Then, I thought that I could try to create a converter that would be bound to the content property of a gridviewcell, and depending of the type of the cell content, it would format differently. (so that I could change both string, date and int format if I want)

    I tried a code like

    Binding convert = new Binding();
    convert.Converter= new DateConverter();
    MyRadGrid.SetBinding(GridViewCell.ContentProperty, convert)

    If it compiles fine, it gave me en HRESULT exception, E_UNEXPECTED at the setBinding line.

    I can't figure out why, could it be because there isn't a binding source ?

    Can anyone tell me if I'm going in a completely wrong direction or just if I'm forgetting something.

    Thanks

    Ludovic
  2. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 21 Aug 2009 Link to this post

    Hello Subileau Pascal,

    You should set a converter on the GridViewDataColumn.DataMemberBinding property like this:

                GridViewDataColumn dynamicColumn = new GridViewDataColumn(); 
                dynamicColumn.Header = "Est."
                dynamicColumn.DataMemberBinding = new Binding("Established"); 
                dynamicColumn.DataMemberBinding.Converter = new DummyConverter(); 
                this.clubsGrid.Columns.Add(dynamicColumn); 
     

    Please see the attached sample project.

    Best wishes,
    Ross
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  3. DevCraft banner
  4. Ludovic Gerbault
    Ludovic Gerbault avatar
    226 posts
    Member since:
    Apr 2009

    Posted 21 Aug 2009 Link to this post

    Yeah, I've tried that already, when I was working with DataFormatString

    But my datacolumns are automatically generated when I set the ItemSource property, I can't add them just like that.

    My problem comes from the fact that the same column in the datagrid can display anything, it's not a fixed column.

    For instance, there are times when a column x will display a date, and there are other times when the same column x will display names or citys or anything.

    You see the problem there.
  5. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 21 Aug 2009 Link to this post

    Hi Ludovic,

    Here is how to do it when the columns are auto-generated:

    using System; 
    using System.Windows.Controls; 
    using Telerik.Windows.Controls; 
     
    namespace TicketID_236856_DataMemberBindingConverter 
        public partial class MainPage : UserControl 
        { 
            public MainPage() 
            { 
                this.InitializeComponent(); 
     
                this.clubsGrid.AutoGeneratingColumn += OnAutoGeneratingColumn; 
                this.clubsGrid.ItemsSource = Club.GetClubs(); 
            } 
     
            private static void OnAutoGeneratingColumn(object sender, GridViewAutoGeneratingColumnEventArgs e) 
            { 
                var dataColumn = e.Column as GridViewDataColumn; 
                if (dataColumn != null
                { 
                    // Place your if logic here, that is just a demo. 
                    if (dataColumn.DataType == typeof (DateTime)) 
                    { 
                        dataColumn.DataMemberBinding.Converter = new DateTimeConverter(); 
                    } 
                    else if (dataColumn.DataType == typeof(string)) 
                    { 
                        //dataColumn.DataMemberBinding.Converter = new SomeOtherConverter(); 
                    } 
                } 
            } 
        } 

    I have modified and attached the project.

    Best wishes,
    Ross
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  6. Ludovic Gerbault
    Ludovic Gerbault avatar
    226 posts
    Member since:
    Apr 2009

    Posted 21 Aug 2009 Link to this post

    Thanks, this works great.

    Except for one detail, all my columns are set as string by default.

    I have a way to know though what exactly is the type of each column each time.
    Is there a way to change the type of an autogenerated column ?

    If not, I'll just a workaround.
  7. Answer
    Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 21 Aug 2009 Link to this post

    Hi  Ludovic,

    Since I am not entirely familiar with architecture and business logic of your application, it is up to you to decide what to do with each column when it arrives in the AutoGeneratingColumn event. You can detect the name of the property that this column is generated for like this:

            private static void OnAutoGeneratingColumn(object sender, GridViewAutoGeneratingColumnEventArgs e) 
            { 
                var dataColumn = e.Column as GridViewDataColumn; 
                if (dataColumn != null
                { 
                    // Place your if logic here, that is just a demo. 
                    if (dataColumn.DataMemberBinding.Path.Path == "DateString"
                    { 
                        dataColumn.DataMemberBinding.Converter = new StringToDateTimeConverter(); 
                        dataColumn.DataType = typeof (DateTime); 
                    } 
                } 
            } 
     

        public class StringToDateTimeConverter : IValueConverter 
        { 
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
            { 
                DateTime result; 
                DateTime.TryParse((string) value, out result); 
                return result; 
            } 
     
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
            { 
                throw new NotImplementedException(); 
            } 
        } 
     

    Based on which column has arrived you can change the type and assign the appropriate converter that will convert the string to this type.

    I have modified the project and attached it again.

    Sincerely yours,
    Ross
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  8. Ludovic Gerbault
    Ludovic Gerbault avatar
    226 posts
    Member since:
    Apr 2009

    Posted 21 Aug 2009 Link to this post

    Thanks you very much, that's actually exactly what I did, but I wasn't familiar with the tryparse method, that will be of great help.

    Anyway, I got my answer, so thanks again.
  9. Sergey Arutchev
    Sergey Arutchev avatar
    14 posts
    Member since:
    Sep 2009

    Posted 05 Nov 2009 Link to this post

    This approach no longer seems to work in Q3.  The DataMemberBinding property of each column is NULL in the AutoGeneratingColummn event handler.  A simple example is below (the XAML just contains a single RadGridView named ResultsGrid with no XML attributes or content).  What is the preferred way to go about this in Q3?


    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Controls;

    public partial class MainPage : UserControl{
        public MainPage()     {
            InitializeComponent();
            this.ResultsGrid.AutoGeneratingColumn += (sender, e) =>           {
                    var col = e.Column as Telerik.Windows.Controls.GridViewDataColumn;
                    if (col != null && col.DataMemberBinding == null )                   
                        System.Windows.MessageBox.Show(string.Format("DataMemberBinding for column {0} is null", col.UniqueName));                                                                
                };         
            this.ResultsGrid.ItemsSource = CreateDataSource();
            return;
        }

        public IEnumerable<TestSource> CreateDataSource(){ return Enumerable.Range(0, 10).Select(x => new TestSource() {Name = "Name" + x.ToString(), Amount = 10000000 * x});}
        public class TestSource {  public string Name { get; set; } public double Amount { get; set; } }
    }
  10. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 06 Nov 2009 Link to this post

    Hello Sergey Arutchev,

    This is a known issue and we are currently working on it. Until we fix it, can you try the following workaround:

    void playersGrid_AutoGeneratingColumn(object sender, GridViewAutoGeneratingColumnEventArgs e)
    {
        var column = e.Column as GridViewDataColumn;
        if (column != null)
        {
            column.DataMemberBinding = new Binding(column.UniqueName);
            //...
        }
    }

    Let us know if this does not resolve the issue.

    All the best,
    Ross
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  11. Patrick Holloway
    Patrick Holloway avatar
    13 posts
    Member since:
    Sep 2009

    Posted 23 Nov 2009 Link to this post

    Is there a solution to this issue yet?

    Add it to the growing list of things that Q3 GridView has broken....

  12. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 26 Nov 2009 Link to this post

    Hello Patrick Holloway,

    1. You need to specify the IValueConverters before binding the grid, in the CreateColumn method. But I do not think you will be needing them at all. See the next points.

    2 & 3. With Q3 we have made several changes. If there is an IValueConverter the edit mode will take it into account. That is it will use the converted value which would have to be converted back when editing finishes.

    This means that if you decide to stick to converters you will have to rewrite your ConvertBack method to receive a string such as "$0.00" and return the double 0. But we have a better suggestion. If you are using this converter with the sole purpose of displaying currency, the the proper way to do this would be to use the column's DataFormatString property like this:

    col.DataFormatString = "{0:C}";

    This will have two benefits -- in edit mode you will see pure raw numbers (without the currency sign) and you will not have to implement a ConvertBack method that parses currency strings.

    I have modified and attached the project. It is using our latest internal build binaries.

    I hope this helps. Let me know if there are other issues.

    All the best,
    Ross
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Back to Top
DevCraft banner