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

What was the feedback?

3 Answers 147 Views
Spreadsheet
This is a migrated thread and some comments may be shown as answers.
Psyduck
Top achievements
Rank 5
Bronze
Bronze
Bronze
Psyduck asked on 06 Apr 2021, 04:49 AM

Hello.

I have previously posted a post.Please refer to the link.

SpreadSheet Cell changed event infinite loop.

Spreadsheet: InvalidOperationException is thrown when attaching to CellPropertyChanged event and trying to modify the cell

 

I tested it after seeing it was updated and built today.

But I don't know what has changed.

Still, errors and infinite loops appear. (System.StackOverflowException: ''System.StackOverflowException' )

 

Thanks.

3 Answers, 1 is accepted

Sort by
0
Psyduck
Top achievements
Rank 5
Bronze
Bronze
Bronze
answered on 06 Apr 2021, 04:57 AM

This is the test code I made.

ref 2021_1_405 xaml

Windows.Data, Windows.Controls,

Controls.Input, Controls.SpreadSheet, Controls.SpreadSheetUI

Documents.Core, Documents.FormatProviders.OpenXml, Documents.Spreadsheet,

Documents.Spreadsheet.FormatProviders.OpenXml, Documents.Spreadsheet.FormatProviders.Pdf

(Xaml and ViewModel.cs)

<Window x:Class="InfiniteLoop.MainWindow"
        xmlns:local="clr-namespace:InfiniteLoop"
        xmlns:Controls="clr-namespace:Telerik.Windows.Controls.Spreadsheet.Controls;assembly=Telerik.Windows.Controls.Spreadsheet"
        xmlns:Xlsx="clr-namespace:Telerik.Windows.Documents.Spreadsheet.FormatProviders.OpenXml.Xlsx;assembly=Telerik.Windows.Documents.Spreadsheet.FormatProviders.OpenXml"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="450" Width="800">
 
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
     
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="80"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
 
        <StackPanel Grid.Column="0">
                <Button Content="1. Add!" Height="40" Width="70" Margin="0 10"
                    Command="{Binding OnClickAddSheetCommand}"
                    />
                <Button Content="2. Change!" Height="40" Width="70"
                    Command="{Binding OnClickChagneSheetCommand}"
                    />
        </StackPanel>
 
        <Grid x:Name="spreadsheetLayoutRoot" Grid.Column="1" >
            <Grid.RowDefinitions>
                <RowDefinition Height="0"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Controls:RadSpreadsheetFormulaBar Grid.Row="1" RadSpreadsheet="{Binding ElementName=radSpreadsheet, Mode=OneTime}"/>
            <telerik:RadSpreadsheet Grid.Row="2"
                                    x:Name="radSpreadsheet"
                                    Workbook="{Binding ExcelSheet}"
                                    AllowDrop="False"
                                    IsTabStop="True"
                                    >
                <telerik:EventToCommandBehavior.EventBindings>
                    <telerik:EventBinding EventName="ActiveSheetChanged"
                                          Command="{Binding OnActiveSheetChangedCommand}"
                                          CommandParameter="{Binding ElementName=radSpreadsheet}"
                                          />
                </telerik:EventToCommandBehavior.EventBindings>
 
                <telerik:RadSpreadsheet.FormatProviders>
                    <Xlsx:XlsxFormatProvider />
                </telerik:RadSpreadsheet.FormatProviders>
            </telerik:RadSpreadsheet>
            <Controls:RadSpreadsheetStatusBar Grid.Row="3" RadSpreadsheet="{Binding ElementName=radSpreadsheet, Mode=OneTime}" Background="SteelBlue" Foreground="White"/>
        </Grid>
    </Grid>
</Window>
using System.Windows.Input;
using System.Windows.Media;
using Telerik.Windows.Controls;
using Telerik.Windows.Documents.Spreadsheet.Model;
using Telerik.Windows.Documents.Spreadsheet.PropertySystem;
 
namespace InfiniteLoop
{
    public class MainWindowViewModel : ViewModelBase
    {
        private Workbook _excelSheet = new Workbook();
        public Workbook ExcelSheet
        {
            get => _excelSheet;
            set
            {
                _excelSheet = value;
                OnPropertyChanged("ExcelSheet");
            }
        }
 
        public ICommand OnClickAddSheetCommand { get; set; }
        public ICommand OnClickChagneSheetCommand { get; set; }
        public ICommand OnActiveSheetChangedCommand { get; set; }
 
        public MainWindowViewModel()
        {
            OnClickAddSheetCommand = new DelegateCommand(OnClickAddSheet);
            OnClickChagneSheetCommand = new DelegateCommand(OnClickChagneSheet);
            OnActiveSheetChangedCommand = new DelegateCommand(OnActiveSheetChanged);
        }
 
        private void OnClickAddSheet(object obj)
        {
            var workBook = new Workbook();
            workBook.Worksheets.Add();
            workBook.Worksheets.Add();
            workBook.Worksheets.Add();
            workBook.Worksheets.Add();
            workBook.Worksheets.Add();
 
            foreach (Worksheet sheet in workBook.Sheets)
            {
                for (int i = 0; i < 5; i++)
                {
                    sheet.Cells[0, i].SetValueAsText($"A");
                }
            }
 
            ExcelSheet = workBook;
        }
 
        private void OnClickChagneSheet(object obj)
        {
            foreach (Worksheet sheet in ExcelSheet.Sheets)
            {
                sheet.Cells[0, 1].SetValueAsText("");
                sheet.Cells[0, 2].SetValueAsText("1");
                sheet.Cells[0, 3].SetValueAsText("");
                sheet.Cells[0, 4].SetValueAsText("0");
            }
        }
         
        private void OnActiveSheetChanged(object spreadsheet)
        {
            var sheet = spreadsheet as RadSpreadsheet;
 
            var worksheetEditor = sheet.ActiveWorksheetEditor;
            if (worksheetEditor != null)
            {
                sheet.ActiveWorksheet.Cells.CellPropertyChanged += OnCellPropertyChangedEvent;
            }
        }
 
        private void OnCellPropertyChangedEvent(object sender, CellPropertyChangedEventArgs e)
        {
                CellSelection cell = (sender as Cells)[e.CellRange];
                var values = cell.GetValue().Value.RawValue;
                if (string.IsNullOrEmpty(values))
                {
                    //Red
                    cell.SetFill(new PatternFill(PatternType.Solid, Color.FromRgb(255, 0, 0), Colors.Transparent));
                }
                else if (values == "1")
                {
                    //Yellow
                    cell.SetFill(new PatternFill(PatternType.Solid, Color.FromRgb(255, 231, 0), Colors.Transparent));
                }
                else
                {
                    cell.ClearFill();
                }
        }
    }
}
0
Nikolay Demirev
Telerik team
answered on 06 Apr 2021, 10:07 AM

Hello Kim,

I have reviewed the code you have sent. There is something that grabbed my attention. The event handler of the CellPropertyChanged is changing the fill property, which causes a new CellPropertyChanged event. Then the fill is changed again, and the event is triggered again. This is causing a StackOverflowException. 

To correctly implement the event handler, you have to check which property is changed and handle only the Value property events. Here is a sample code showing how to do that:

private void OnCellPropertyChangedEvent(object sender, CellPropertyChangedEventArgs e)
{
    if (e.Property == CellPropertyDefinitions.ValueProperty)
    {
        CellSelection cell = (sender as Cells)[e.CellRange];
        string values = cell.GetValue().Value.RawValue;
        if (string.IsNullOrEmpty(values))
        {
            //Red
            cell.SetFill(new PatternFill(PatternType.Solid, Color.FromRgb(255, 0, 0), Colors.Transparent));
        }
        else if (values == "1")
        {
            //Yellow
            cell.SetFill(new PatternFill(PatternType.Solid, Color.FromRgb(255, 231, 0), Colors.Transparent));
        }
        else
        {
            cell.ClearFill();
        }
    }
}

Please let me know if you have any additional questions.

Regards,
Nikolay Demirev
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products, quickly just got a fresh new look + new and improved content, including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Psyduck
Top achievements
Rank 5
Bronze
Bronze
Bronze
answered on 07 Apr 2021, 04:41 AM

Hello.

 

This works perfectly.

The previous source had "e.Property == CellPropertyDefinitions.ValueProperty", but it changed and overlooked.

 

Thnak you.

Tags
Spreadsheet
Asked by
Psyduck
Top achievements
Rank 5
Bronze
Bronze
Bronze
Answers by
Psyduck
Top achievements
Rank 5
Bronze
Bronze
Bronze
Nikolay Demirev
Telerik team
Share this question
or