Disabling all but one child control in a WPF window
Asked Answered
S

3

18

I have a bunch of controls on my window. One of them is a refresh button that performs a cumbersome task on a background thread.

When the user clicks the refresh button, I put the cursor in a wait (hourglass) status and disable the whole window -- Me.IsEnabled = False.

I'd like to support cancellation of the refresh action by letting the user click a cancel button, but I can't facilitate this while the whole window is disabled.

Is there a way to do this besides disabling each control (except for the cancel button) one by one and then re-enabling them one by one when the user clicks cancel?

Sandler answered 7/11, 2008 at 22:11 Comment(1)
I can't seem to use both Me.IsEnabled and Me.Cursor. #762896Bruiser
D
23

You can put all the controls in one panel (Grid, StackPanel, etc.), and leave the cancel button in another panel. Then set the IsEnabled property of the other panel.

In practice, this will probably introduce more than one additional panel.

For example, if you had a StackPanel of buttons, you can add an additional StackPanel:

<StackPanel Orientation="Horizontal">
    <StackPanel x:Name="controlContainer" Orientation="Horizontal">
        <!-- Other Buttons Here -->
    </StackPanel>
    <Button Content="Cancel" />
</StackPanel>

Then, you would do the following to disable everything but the cancel button:

controlContainer.IsEnabled = false;
Deaton answered 7/11, 2008 at 22:33 Comment(2)
StackPanel doesn't have an IsEnabled property in WP8Autocade
Well, I have done 0 work with WP8, but I found the docs for the WP8 StackPanel: msdn.microsoft.com/en-US/library/windows/apps/… I assume you're using that api, and not the Silverlight one, since Silverlight has an IsEnabled property. While you won't get the exact look of disabled controls, you could always set the IsHitTestVisible="false" to disable input on controlContainer. Otherwise, you could have a semi-transparent overlay that you make visible when you want to disable the other controls (and use a Grid as the outer panel).Deaton
B
5

I also wanted the user to be able to cancel out of loading. I found a lovely solution.

foreach (Control ctrl in this.Controls)
    ctrl.Enabled = false;

CancelButton.Enabled = true;

This also allows the main window to be selected and moved unlike this.Enabled = false; which completely locks up the window.

Balcom answered 7/2, 2011 at 22:0 Comment(1)
Control doesn't have an IsEnabled property in WP8Autocade
J
3

You can data bind each controls IsEnabled property to your custom boolean dependency property that signals when your application is in lock down. Just don't bind the cancel button.

As Donnelle mentioned You can setup multi binding with a converter. Here are a couple examples you can refer to. WPF MultiBinding with Converter Implementing Parameterized MultiBinding Sample

Jehovah answered 7/11, 2008 at 22:30 Comment(2)
The only problem I have w/ that is that the IsEnabled property on some of my controls is already data bound to a boolean property for other purposes.Sandler
You could use a multi-binding with a converter-- there are examples around for how to do a generic one with a parameter for AND or OR behaviours.Damal

© 2022 - 2024 — McMap. All rights reserved.