I am using the latest release. I have this code -- I even tried manually forcing the selection, but it didn't help any:
Workbook spreadsheetWorkbook =
new
XlsxFormatProvider( ).Import( result );
//I tried to force the active worksheet, but this doesn't help either!
spreadsheetWorkbook.ActiveWorksheet = spreadsheetWorkbook.Worksheets.FirstOrDefault( );
foreach
( var sheet
in
spreadsheetWorkbook.Worksheets )
{
sheet.ViewState.IsSelected =
false
;
}
if
( spreadsheetWorkbook.ActiveWorksheet !=
null
)
{
spreadsheetWorkbook.ActiveWorksheet.ViewState.IsSelected =
true
;
}
spreadsheet.Workbook = spreadsheetWorkbook;
And the result is attached.
Please advise...
Regards,
8 Answers, 1 is accepted
Hi Mark,
I have tested this and it is working on my side. For convenience, I prepared a small sample, based on the information that you provided so far and attached it to this thread. Could you please check it and let me know how it differs from your real setup? Could you test this with your file and my application?
Thank you in advance for your patience and cooperation.
Regards,
Dimitar
Progress Telerik
To reproduce, just make the spreadsheet disabled while populating the control. In our UI, the spreadsheet's ancestors are disabled until the data have been loaded asynchronously, and if the spreadsheet is disabled the worksheet will not be activated properly.
<
telerik:RadSpreadsheet
x:Name
=
"radSpreadsheet"
Grid.Row
=
"2"
IsEnabled
=
"False"
>
And in the code behind:
private
void
RadButton_Click(
object
sender, RoutedEventArgs e )
{
radSpreadsheet.IsEnabled =
false
;
Workbook spreadsheetWorkbook =
new
XlsxFormatProvider( ).Import( File.ReadAllBytes( @
"..\..\Book2.xlsx"
) );
//I tried to force the active worksheet, but this doesn't help either!
//spreadsheetWorkbook.ActiveWorksheet = spreadsheetWorkbook.Worksheets.FirstOrDefault( );
//foreach ( Worksheet sheet in spreadsheetWorkbook.Worksheets )
//{
// sheet.ViewState.IsSelected = false;
//}
//if ( spreadsheetWorkbook.ActiveWorksheet != null )
//{
// spreadsheetWorkbook.ActiveWorksheet.ViewState.IsSelected = true;
//}
radSpreadsheet.Workbook = spreadsheetWorkbook;
radSpreadsheet.IsEnabled =
true
;
}
Putting in the manual selection code doesn't help. However, if I move the selection code to after the control is enabled again, I can
private
void
RadButton_Click(
object
sender, RoutedEventArgs e )
{
radSpreadsheet.IsEnabled =
false
;
Workbook spreadsheetWorkbook =
new
XlsxFormatProvider( ).Import( File.ReadAllBytes( @
"..\..\Book2.xlsx"
) );
radSpreadsheet.Workbook = spreadsheetWorkbook;
radSpreadsheet.IsEnabled =
true
;
spreadsheetWorkbook.ActiveWorksheet = spreadsheetWorkbook.Worksheets.LastOrDefault( );
foreach
( Worksheet sheet
in
spreadsheetWorkbook.Worksheets )
{
sheet.ViewState.IsSelected =
false
;
}
spreadsheetWorkbook.ActiveWorksheet = spreadsheetWorkbook.Worksheets.FirstOrDefault( );
if
( spreadsheetWorkbook.ActiveWorksheet !=
null
)
{
spreadsheetWorkbook.ActiveWorksheet.ViewState.IsSelected =
true
;
}
}
This seems the simplest workaround, but also a hack!
private
void
RadButton_Click(
object
sender, RoutedEventArgs e )
{
radSpreadsheet.IsEnabled =
false
;
Workbook spreadsheetWorkbook =
new
XlsxFormatProvider( ).Import( File.ReadAllBytes( @
"..\..\Book2.xlsx"
) );
Dispatcher dispatcher = Dispatcher;
radSpreadsheet.Workbook =
new
Workbook( );
Task.Factory.StartNew(
( ) => dispatcher.InvokeAsync(
( ) => radSpreadsheet.Workbook = spreadsheetWorkbook ) );
radSpreadsheet.IsEnabled =
true
;
}
Hi Mark,
It is not recommended to update UI controls from other than the UI thread. I would recommend separating the import process in another thread and enabling the control before setting the workbook:
BackgroundWorker worker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
radSpreadsheet.IsEnabled = false;
worker.DoWork += Worker_DoWork;
worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
radSpreadsheet.IsEnabled = true;
var workbook = e.Result as Workbook;
radSpreadsheet.Workbook = workbook;
}
private void RadButton_Click(object sender, RoutedEventArgs e)
{
worker.RunWorkerAsync();
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Workbook spreadsheetWorkbook = new XlsxFormatProvider().Import(File.ReadAllBytes(@"..\..\Book2.xlsx"));
e.Result = spreadsheetWorkbook;
}
Does this approach work for your case?
I am looking forward to your reply.
Regards,
Dimitar
Progress Telerik
While I appreciate the effort in your last response, it is not relevant. The sample code I previously provided shows how to reproduce the bug, and the followup post shows a temporary workaround. The workaround is not acceptable in the long run -- the bug needs to be fixed. The workaround I provided violates the MVVM pattern.
You may have been confused by my previous use of Task.Factory, however it is ultimately going back to the dispatcher. So the UI operations are all on the UI thread. I found though that only the briefest of delays is required to workaround the bug. So, this slightly simpler code also works to avoid the bug:
private
void
RadButton_Click(
object
sender, RoutedEventArgs e )
{
radSpreadsheet.IsEnabled =
false
;
Workbook spreadsheetWorkbook =
new
XlsxFormatProvider( ).Import( File.ReadAllBytes( @
"..\..\Book2.xlsx"
) );
radSpreadsheet.Workbook =
new
Workbook( );
Dispatcher.InvokeAsync( ( ) => radSpreadsheet.Workbook = spreadsheetWorkbook );
radSpreadsheet.IsEnabled =
true
;
}
In our application, we have an async operation that sets an IsBusy property to true on the view model, which triggers some loading animations and also sets the RadSpreadsheet's IsEnabled to false. When the workbook is loaded, it is assigned to a property and the RadSpreadsheet's Workbook property is bound to the view model's Workbook property. After the loading is completed, the IsBusy property is set to false on the view model, which completes the animations and enables the RadSpreadsheet.
So, it is a potential bug and race condition to use the dispatcher to set the workbook property after enabling the RadSpreadsheet control (etc.). I am doing just that as a temporary workaround until the bug is fixed by Telerik.
Hi Mark,
Ok, I believe this can be improved as well. This is why I have logged it on our feedback portal. You can track its progress, subscribe to status changes and add your comment to it here. I have updated your Telerik points as well.
Until this is resolved I believe it is safe to use your workaround.
Let me know if you have any other questions.
Regards,
Dimitar
Progress Telerik