This is a migrated thread and some comments may be shown as answers.

Issue with ExportToXlsx()

4 Answers 302 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Non
Top achievements
Rank 1
Non asked on 09 Oct 2018, 11:12 AM

Hello,

I have some of GridViewCheckBoxColumn and GridViewComboBoxColumn that bound to nested property which works perfectly. But when I try to use ExportToXlsx() to export into excel file, result from every columns that bound to nested property are different.

GridViewCheckBoxColumn bound to nested property yields True/False instead of TRUE/FALSE and GridViewComboBoxColumn yields selected value instead of display value which I preferred display value.

Is there anyway to make all columns regardless of nested property binding to be exported in the same format?

 

Here's my sample code

<Window x:Class="WpfApplication3.Window4"
        xmlns:local="clr-namespace:WpfApplication3"
        mc:Ignorable="d"
        Title="Window4" Width="800" Height="300" >
    <StackPanel>
        <telerik:RadGridView Name="grid1" ItemsSource="{Binding GridItemSoure}" AutoGenerateColumns="False">
            <telerik:RadGridView.Columns>
                <telerik:GridViewDataColumn Header="Display" DataMemberBinding="{Binding Display}"/>
                <telerik:GridViewCheckBoxColumn Header="IsChecked" DataMemberBinding="{Binding IsChecked}"/>
                <telerik:GridViewComboBoxColumn Header="SelectedItem" DataMemberBinding="{Binding SelectedItemId}" ItemsSource="{Binding ComboItemSource}" DisplayMemberPath="Display" SelectedValueMemberPath="Id"/>
                <telerik:GridViewDataColumn Header="Amount" DataMemberBinding="{Binding Amount}"/>
                <telerik:GridViewDataColumn Header="This.Display" DataMemberBinding="{Binding This.Display}"/>
                <telerik:GridViewCheckBoxColumn Header="This.IsChecked" DataMemberBinding="{Binding This.IsChecked}"/>
                <telerik:GridViewComboBoxColumn Header="This.SelectedItem" DataMemberBinding="{Binding This.SelectedItemId}" ItemsSource="{Binding ComboItemSource}" DisplayMemberPath="Display" SelectedValueMemberPath="Id"/>
                <telerik:GridViewDataColumn Header="This.Amount" DataMemberBinding="{Binding This.Amount}"/>
            </telerik:RadGridView.Columns>
        </telerik:RadGridView>
        <Button Click="Button_Click">Export</Button>
    </StackPanel>
</Window>
public partial class Window4 : Window
{
    public Window4()
    {
        InitializeComponent();
 
        this.DataContext = new
        {
            GridItemSoure = new List<RowItem>()
            {
                new RowItem() { Display = "Row1", IsChecked = true, SelectedItemId = null, Amount = 9.999m },
                new RowItem() { Display = "Row2", IsChecked = false, SelectedItemId = null, Amount = 10000 },
                new RowItem() { Display = "Row3", IsChecked = true, SelectedItemId = 2, Amount = 1/3 },
                new RowItem() { Display = "Row4", IsChecked = false, SelectedItemId = 3, Amount = -1/3 },
            },
            ComboItemSource = new List<Item>()
            {
                new Item() { Id = 1, Display = "Item 1" },
                new Item() { Id = 2, Display = "Item 2" },
                new Item() { Id = 3, Display = "Item 3" },
            },
        };
    }
 
    private void Button_Click(object sender, RoutedEventArgs e)
    {
 
        string extension = "xlsx";
        SaveFileDialog dialog = new SaveFileDialog()
        {
            DefaultExt = extension,
            Filter = String.Format("{1} files (*.{0})|*.{0}|All files (*.*)|*.*", extension, "Excel Workbook"),
            FilterIndex = 1
        };
        if (dialog.ShowDialog() == true)
        {
            using (Stream stream = dialog.OpenFile())
            {
                grid1.ExportToXlsx(stream, new GridViewDocumentExportOptions()
                {
                    ShowColumnHeaders = true,
                    ShowColumnFooters = true,
                    ShowGroupFooters = true,
                    AutoFitColumnsWidth = true,
                    ExportDefaultStyles = false,
                });
            }
        }
    }
}
 
public class RowItem : INotifyPropertyChanged
{
    private string _Display;
    public string Display
    {
        get { return _Display; }
        set
        {
            this._Display = value;
            OnPropertyChanged(nameof(Display));
        }
    }
 
    private bool _IsChecked;
    public bool IsChecked
    {
        get { return _IsChecked; }
        set
        {
            this._IsChecked = value;
            OnPropertyChanged(nameof(IsChecked));
        }
    }
 
    private int? _SelectedItemId;
    public int? SelectedItemId
    {
        get { return _SelectedItemId; }
        set
        {
            this._SelectedItemId = value;
            OnPropertyChanged(nameof(SelectedItemId));
        }
    }
 
    private decimal? _Amount;
    public decimal? Amount
    {
        get { return _Amount; }
        set
        {
            this._Amount = value;
            OnPropertyChanged(nameof(Amount));
        }
    }
 
    public RowItem This
    {
        get
        {
            return this;
        }
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
 
    private void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}
 
public class Item : INotifyPropertyChanged
{
    private string _Display;
    public string Display
    {
        get { return _Display; }
        set
        {
            this._Display = value;
            OnPropertyChanged(nameof(Display));
        }
    }
 
    private int? _Id;
    public int? Id
    {
        get { return _Id; }
        set
        {
            this._Id = value;
            OnPropertyChanged(nameof(Id));
        }
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
 
    private void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}

 

Thanks

4 Answers, 1 is accepted

Sort by
0
Vladimir Stoyanov
Telerik team
answered on 12 Oct 2018, 09:29 AM
Hello,

Thank you for the attached snippets.

I thoroughly investigated the described scenario and the behavior comes from the fact that there is separate logic for extracting the cell value when there is a nested binding.

I am attaching a sample project where I have demonstrated how you can use the ElementExportingToDocument event in order to achieve the same export for both nested and non-nested bindings of a checkbox column. That said I was not able to reproduce the described behavior with regards to the combobox column on my end. I also attached a sample file where you can observe that both ComboBoxColumns are exported in the same way. Can you check out the attached project and let me know if I am missing something?

I hope you find this helpful.

Regards,
Vladimir Stoyanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Non
Top achievements
Rank 1
answered on 16 Oct 2018, 05:22 AM

Hello,

I have tested your sample project and attached a picture of output excel, the result of This.SelectedItem are 2,3 while SelectedItem are Item 2/Item 3.

By the way, i'm using build 2017.2.614.40.

Thanks

0
Accepted
Dilyan Traykov
Telerik team
answered on 17 Oct 2018, 12:17 PM
Hello Non,

This issue is related to the following bug which was fixed with the R2 2018 release of the UI for WPF suite. If possible, please update to this version of the controls to resolve the issue.

If you're unable to do so, you can use reflection to get ahold of the desired display value. Here's how you can achieve that in the project Vladimir provided in his previous reply:

private void grid1_ElementExportingToDocument(object sender, GridViewElementExportingToDocumentEventArgs e)
{
    if (e.Element == ExportElement.Cell)
    {
        var cellExportingArgs = e as GridViewCellExportingEventArgs;
 
        if (e.Value?.ToString() == "True")
        {
            e.Value = "TRUE";
        }
        else if (e.Value?.ToString() == "False")
        {
            e.Value = "FALSE";
        }
 
        var comboColumn = cellExportingArgs.Column as GridViewComboBoxColumn;
        if (comboColumn != null)
        {
            var source = comboColumn.ItemsSource;
            var type = comboColumn.DataType;
            var value = GetPropertyValue(e.DataContext, comboColumn.DataMemberBinding.Path.Path);
            if (value != null)
            {
                foreach (var item in source)
                {
                    var compareValue = GetPropertyValue(item, comboColumn.SelectedValueMemberPath);
                    if (value.Equals(compareValue))
                    {
                        e.Value = GetPropertyValue(item, comboColumn.DisplayMemberPath);
                    }
                }
            }
        }
    }
}
 
public object GetPropertyValue(object obj, string propertyName)
{
    foreach (var prop in propertyName.Split('.').Select(s => obj.GetType().GetProperty(s)))
    {
        obj = prop.GetValue(obj, null);
    }
 
    return (object)obj;
}

Please let me know whether such an approach would work for you.

Regards,
Dilyan Traykov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Non
Top achievements
Rank 1
answered on 18 Oct 2018, 08:15 AM

Hello,

 

I can't update the version at this time, so I'll take your sample code to workaround.

Thanks for your support.

 

Regards,

Tags
GridView
Asked by
Non
Top achievements
Rank 1
Answers by
Vladimir Stoyanov
Telerik team
Non
Top achievements
Rank 1
Dilyan Traykov
Telerik team
Share this question
or