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

Databinding the IsBackstageOpen property does not have any effect

11 Answers 109 Views
RibbonView and RibbonWindow
This is a migrated thread and some comments may be shown as answers.
ITC
Top achievements
Rank 1
ITC asked on 08 Dec 2011, 01:47 PM
Hi

I would like to control the visibility of the backstage component via my viewmodel through databinding, see below.

IsBackstageOpen="{Binding BackstageIsOpen}"

Although I get no errors, the ribbon is not responding to changes in my property value. (I am notifying the property change).

Any ideas?

11 Answers, 1 is accepted

Sort by
0
Viktor Tsvetkov
Telerik team
answered on 08 Dec 2011, 02:14 PM
Hi Dirk,

Could you please try setting Mode="TwoWay" in the binding expression and tell me if it works for you?

Kind regards,
Viktor Tsvetkov
the Telerik team

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

0
ITC
Top achievements
Rank 1
answered on 08 Dec 2011, 02:24 PM
Thanks it solves 99% of the problem - the backstage is responding to me closing it from the viewmodel.

The last remaining issue is that I would like the application to start with the Backstage open. Usually you would set it in the XAML and all would be well.

Because I'm using databinding I set my BackstageIsOpen property to true in the constructor of my viewmodel, but the backstage does not respond.
0
ITC
Top achievements
Rank 1
answered on 08 Dec 2011, 02:54 PM
After some more testing it seems that the IsBackStateOpen property only responds to "False" values if set through databinding. I am unable to make the backstage appear from the viewmodel at any time.
0
Viktor Tsvetkov
Telerik team
answered on 08 Dec 2011, 04:07 PM
Hello Dirk,

Could you please examine the attached sample project and tell me if it works for you?

Best wishes,
Viktor Tsvetkov
the Telerik team

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

0
ITC
Top achievements
Rank 1
answered on 08 Dec 2011, 06:06 PM
Hi Viktor

Your sample works, but I have tracked down the problem. I am executing code using Task.Factory.StartNew and then setting the property thereafter. When I do that in your sample it fails as well.

How can I upload a sample to you? The attach file won't allow my zipfile to be uploaded.
0
ITC
Top achievements
Rank 1
answered on 08 Dec 2011, 08:46 PM
Hi Viktor

Make the following changes to the code behind of your sample

/// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
 
            (this.DataContext as MainViewModel).IsBackstageOpen = true;
        }
 
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var dataContext = this.DataContext as MainViewModel;
            dataContext.DoLongRunningProcess();
        }
    }
 
    public class MainViewModel : ViewModelBase
    {
        private bool isBackstageOpen;
 
        private bool isBusy;
 
        public bool IsBackstageOpen
        {
            get
            {
                return isBackstageOpen;
            }
            set
            {
                isBackstageOpen = value;
                OnPropertyChanged("IsBackstageOpen");
            }
        }
 
        public bool IsBusy
        {
            get { return this.isBusy; }
            set { this.isBusy = value;
                OnPropertyChanged(() => this.IsBusy);
            }
        }
         
 
        public void DoLongRunningProcess()
        {
            this.IsBusy = true;
 
            this.IsBackstageOpen = !this.IsBackstageOpen;
 
            var task = Task.Factory.StartNew(() => Thread.Sleep(1000));
 
            Task.WaitAll(task);
 
            this.IsBusy = false;
            this.IsBackstageOpen = !this.IsBackstageOpen;
 
        }
    }

then change your XAML to wrap the stackpanel in a IsBusyIndicator as follows

<telerik:RadBusyIndicator IsBusy="{Binding IsBusy}" >
        <StackPanel>
            <Button Content="Click" Click="Button_Click" />
            <telerik:RadRibbonView IsBackstageOpen="{Binding IsBackstageOpen, Mode=TwoWay}">
                <telerik:RadRibbonTab Header="Tab" />
                <telerik:RadRibbonTab Header="Tab" />
                <telerik:RadRibbonTab Header="Tab" />
                <telerik:RadRibbonView.Backstage>
                    <telerik:RadRibbonBackstage>
                        <telerik:RadRibbonBackstageItem Header="Item" />
                        <telerik:RadRibbonBackstageItem Header="Item" />
                        <telerik:RadRibbonBackstageItem Header="Item" />
                    </telerik:RadRibbonBackstage>
                </telerik:RadRibbonView.Backstage>
            </telerik:RadRibbonView>
        </StackPanel>
    </telerik:RadBusyIndicator>

You will notice two bugs.

1. The backstage no longer responds to changes.
2. The IsBusyIndicator doesn't show up


0
ITC
Top achievements
Rank 1
answered on 12 Dec 2011, 03:01 PM
Hi

Have you been able to test the code I posted?
0
Viktor Tsvetkov
Telerik team
answered on 13 Dec 2011, 09:40 AM
Hi Dirk,

Everything is working as expected in your code. The IsBackstageOpen responds to changes, but you cannot notice them, because if you remove the Thread.Sleep method they will happen too fast and if you leave the method it freezes the UI, so nothing can happen (same with the RadBusyIndicator), so you can try your sample with some code which doesn't freeze the UI (i.e. some calculations in a background thread).

Regards,
Viktor Tsvetkov
the Telerik team

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

0
ITC
Top achievements
Rank 1
answered on 13 Dec 2011, 09:58 AM
Hi Viktor

In my real code I am running calculations that don't affect the UI.

Correct me if I'm wrong, but as I understand it. My Thread.Sleep is running in a background thread. Therefore the UI should not be blocking and the backstage should respond to changes made to its properties.

I have commented the code as I understand it. The question is whether the Task.WaitAll is blocking the UI thread from updating its status...

publicvoidDoLongRunningProcess()
        {
            // I am setting the IsBusy to true but don't expect anything to be visible since I am still busy on the calling thread.
            this.IsBusy = true;
            // I am changing the Backstage open stage but don't expect any change since the UI thread is still locked.
            this.IsBackstageOpen = !this.IsBackstageOpen;
            // I am now sleeping on a background thread which should not lock the UI thread. I am expecting the UI to refresh itself from here on.
            var task = Task.Factory.StartNew(() => Thread.Sleep(1000));
            // The code should now wait for the sleep to finish. This might be blocking code...
            Task.WaitAll(task);
            // We are done with the long running process and we reset the busy indicator etc.
            this.IsBusy = false;
            this.IsBackstageOpen = !this.IsBackstageOpen;
  
        }
0
Accepted
Viktor Tsvetkov
Telerik team
answered on 13 Dec 2011, 12:55 PM
Hello Dirk,

Excuse me for my last post, I was not clear enough. I meant that the action that is being performed (Thread.Sleep) will block the UI, because of the WaitAll method which actually waits for the action to finish. You can set initially the IsBcakstageOpen property to be false, remove the calling of WaitAll method and you will see that for a fraction of a second the backstage is opened and then closed again (this means that it continues to reflect to changes made from the ViewModel).

Kind regards,
Viktor Tsvetkov
the Telerik team

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

0
ITC
Top achievements
Rank 1
answered on 13 Dec 2011, 01:42 PM
Hi Viktor

Thanks for bearing with me. Based on your feedback I was able to get the correct behavior by making use of the synchronization context as follows:

this.IsBusy = true;
 
this.IsBackstageOpen = !this.IsBackstageOpen;
 
var uiContext = TaskScheduler.FromCurrentSynchronizationContext();
 
Task.Factory.StartNew(() => Thread.Sleep(1000)).ContinueWith(t =>
                        {
                            this.IsBusy = false;
                            this.IsBackstageOpen = !this.IsBackstageOpen;
                        }, uiContext);
Tags
RibbonView and RibbonWindow
Asked by
ITC
Top achievements
Rank 1
Answers by
Viktor Tsvetkov
Telerik team
ITC
Top achievements
Rank 1
Share this question
or