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

BusyIndicator override the Command CanExecute from Button

8 Answers 283 Views
BusyIndicator
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Bruno
Top achievements
Rank 1
Bruno asked on 04 Apr 2012, 01:57 PM
Hi Telerik Team

In our project, we have a search (wcf service) where the user can export the result from this search. The Export of this result is handled with a RadButton and Command. (Export is only possible if a result exist!)
During the search, we display a BusyIndicator. When the search is finished and no results were found, the Export Button is still enabled, although the CanExecute of the Export Command is false!

Sample:
First, the two Buttons are disabled (because the Search-Result is null).
When you search for 'test', the Buttons becomes enabled (because 3 Results were found).
Now, when you search for 'testx', only the Button outside of the BusyIndicator becomes disabled. (Search-Result is null). The Button inside the BusyIndicator still is enabled!

Sample code:
<UserControl x:Class="SilverlightApplication3.BusyCommandTest"
    mc:Ignorable="d"
    d:DesignHeight="500" d:DesignWidth="500">
    
   <telerik:RadDockPanel>
      <telerik:RadButton telerik:RadDockPanel.Dock="Top" Content="Command (outside of RadBusyIndicator)" Command="{Binding ExportResultCommand}" Margin="30,30,30,10"/>
      <telerik:RadBusyIndicator IsIndeterminate="True" IsBusy="{Binding IsBusy}" BusyContent="Going on...">
 
         <telerik:RadDockPanel>
            <telerik:RadButton telerik:RadDockPanel.Dock="Top" Content="Command (inside of RadBusyIndicator)" Command="{Binding ExportResultCommand}" Margin="30,0,30,30"/>
            <StackPanel Orientation="Horizontal" telerik:RadDockPanel.Dock="Top" Margin="30">
               <TextBox Text="{Binding SearchTerm, Mode=TwoWay}" Width="300"/>
               <telerik:RadButton Content="Search" Command="{Binding SearchCommand}"/>
               <telerik:RadButton Content="InvalidateCanExecute" Command="{Binding InvalidateCommand}"/>
            </StackPanel>
            <telerik:RadGridView ItemsSource="{Binding ResultList}" Margin="30"/>
         </telerik:RadDockPanel>
 
      </telerik:RadBusyIndicator>
 
   </telerik:RadDockPanel>
</UserControl>


ViewModel (DataContext of UserControl)
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading;
using System.Windows.Input;
using Telerik.Windows.Controls;
 
namespace SilverlightApplication3
{
   public class BusyCommandViewModel : ViewModelBase
   {
      public BusyCommandViewModel()
      {
         this.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(BusyCommandViewModel_PropertyChanged);
      }
 
      void BusyCommandViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
      {
         if (e.PropertyName == "ResultList")
         {
            ExportResultCommand.InvalidateCanExecute();
         }
      }
 
      private bool isBusy;
      public bool IsBusy
      {
         get { return isBusy; }
         set
         {
            isBusy = value;
            this.OnPropertyChanged("IsBusy");
         }
      }
      private string searchTerm;
      public string SearchTerm
      {
         get { return searchTerm; }
         set
         {
            searchTerm = value;
            this.OnPropertyChanged("SearchTerm");
         }
      }
 
      private ICommand searchCommand;
      public ICommand SearchCommand
      {
         get
         {
            if (searchCommand == null)
            {
               searchCommand = new DelegateCommand(this.DoSearch);
            }
            return searchCommand;
         }
      }
 
      private void DoSearch(object param)
      {
         this.IsBusy = true;
 
         // Backgroundworker to Simulate WCF Service Search
         BackgroundWorker worker = new BackgroundWorker();
         worker.DoWork += (sender, e) =>
         {
            Thread.SpinWait(100000000);
         };
         worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
         worker.RunWorkerAsync();
      }
 
      void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
      {
         if (this.SearchTerm == "test")
         {
            ObservableCollection<TestObject> tempList = new ObservableCollection<TestObject>();
            tempList.Add(new TestObject("Entry1.1", "Entry1.2"));
            tempList.Add(new TestObject("Entry2.1", "Entry2.2"));
            tempList.Add(new TestObject("Entry3.1", "Entry3.2"));
            this.ResultList = tempList;
         }
         else
         {
            this.ResultList = null;
         }
 
         this.IsBusy = false;
      }
 
      private DelegateCommand exportResultCommand;
      public DelegateCommand ExportResultCommand
      {
         get
         {
            if (exportResultCommand == null)
            {
               exportResultCommand = new DelegateCommand(this.DoExportResult, this.CanExportResult);
            }
            return exportResultCommand;
         }
      }
 
      private bool CanExportResult(object p)
      {
         bool canExport = this.ResultList != null && this.ResultList.Count > 0;
         return canExport;
      }
 
      private void DoExportResult(object p)
      {
         // Action to Export
      }
 
      private ICommand invalidateCommand;
      public ICommand InvalidateCommand
      {
         get
         {
            if (invalidateCommand == null)
            {
               invalidateCommand = new DelegateCommand(this.DoInvalidate);
            }
            return invalidateCommand;
         }
      }
 
      private void DoInvalidate(object param)
      {
         ExportResultCommand.InvalidateCanExecute();
      }
 
 
      private ObservableCollection<TestObject> resultList;
      public ObservableCollection<TestObject> ResultList
      {
         get { return resultList; }
         set
         {
            resultList = value;
            this.OnPropertyChanged("ResultList");
         }
      }
   }
 
   public class TestObject
   {
      public TestObject(string column1, string column2)
      {
         this.Column1 = column1;
         this.Column2 = column2;
      }
 
      public string Column1 { get; set; }
      public string Column2 { get; set; }
   }
}

Thank you.

8 Answers, 1 is accepted

Sort by
0
Yana
Telerik team
answered on 09 Apr 2012, 11:17 AM
Hello Bruno,

Thank you for reporting this issue, we will research it in more details.  I will write here as soon as we have a result.

Kind regards,
Yana
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Ivo
Telerik team
answered on 10 Apr 2012, 02:47 PM
Hello Bruno,

We have investigated this and an easy workaround for it. You can bind to the IsBusyIndicatorVisible property and you can invalidate the command when the property into your ViewModel changes. Here is sample code:
<telerik:RadBusyIndicator IsBusyIndicationVisible="{Binding IsBusyIndicatorVisible, Mode=TwoWay}"
                                  IsBusy="{Binding IsBusy, Mode=TwoWay}"
                                  BusyContent="Going on...">
....

private bool _IsBusyIndicatorVisible;
public bool IsBusyIndicatorVisible
{
    get
    {
        return this._IsBusyIndicatorVisible;
    }
    set
    {
        if (value != this._IsBusyIndicatorVisible)
        {
            this._IsBusyIndicatorVisible = value;
            this.OnPropertyChanged("IsBusyIndicatorVisible");
            this.exportResultCommand.InvalidateCanExecute();
        }
    }
}

All the best, Ivo
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Bruno
Top achievements
Rank 1
answered on 18 Apr 2012, 06:43 AM
Hi Ivo,

Thank you for the workaround.
In our Architecture with base classes etc., it isn't (easy) possible to implement this workaround.
Is the Bug scheduled for fixing?

Thank you and kind regards,
Bruno
0
Ivo
Telerik team
answered on 23 Apr 2012, 05:13 PM
Hi Bruno,

I believe this issue cannot be fixed at our side for the present. We understand this may not be easy to workaround into your application, but it seems this is the only way to get it working.

All the best, Ivo
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Bruno
Top achievements
Rank 1
answered on 24 Apr 2012, 02:26 PM

Hi Ivo,

Thank you for your answer.
That aren't good news.
Additional information to this bug: With the Standard Silverlight Button (not Telerik RadButton) and the RelayCommand (from MVVM Light Toolkit, not Telerik DelegateCommand), it works! Maybe this could help for fixing the bug.

Kind regards,
Bruno

0
Ivo
Telerik team
answered on 26 Apr 2012, 09:35 AM
Hi Bruno,

Thank you for the additional information.

All the best, Ivo
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Rodro
Top achievements
Rank 2
answered on 05 Jun 2012, 01:33 AM
Hi,

I have identical problems with version 2012 Q1 SP1.
It looks like the RadBusyIndicator, besides displaying the busy overlay which already prevents overlayed controls to be clicked, also set IsEnabled="False" (and back to True) on the ContentControl which hosts the covered visual tree. This somehow interfere with the logic of buttons, which update their IsEnabled property based on their Command binding. Which is weird! A Dependency Property set at an inner level should always override whatever value is set at an outer level.

Anyway, a workaround is to get rid of any fiddling with that property in the BusyIndicator template.
In my tests the overlay was enough to prevent any action on the proteced parts while busy.

But I don't know for sure if there is any reason for actually disabling the control...

-Rodrigo-
0
Bruno
Top achievements
Rank 1
answered on 19 Jun 2012, 01:11 PM
Hi Rodrigo

Thank you for your reply. Your workaround works for me like a charme!
Tags
BusyIndicator
Asked by
Bruno
Top achievements
Rank 1
Answers by
Yana
Telerik team
Ivo
Telerik team
Bruno
Top achievements
Rank 1
Rodro
Top achievements
Rank 2
Share this question
or