Domanda

I've got a WPF application using Caliburn.Micro. I want to be able to overlay the application with a shadow and progress ring (from MahApps.Metro) when I want the application to wait for some work to be done in the background.

What I have at the moment actually works but the overlay is always-on at design time. My ShellView window looks like this:

<Window ...>
    ...
    <Grid>
        ...
        <Rectangle x:Name="waitShadow" Fill="#3f000000" Stroke="Black" StrokeThickness="0" Visibility="{Binding IsWaiting, Converter={StaticResource BooleanToVisibilityConverter}}" Grid.RowSpan="2"/>
        <ContentControl ... Visibility="{Binding IsWaiting, Converter={StaticResource BooleanToVisibilityConverter}}">
            <Controls:ProgressRing ...> <!-- from MahApps.Metro -->
            </Controls:ProgressRing>
        </ContentControl>
    </Grid>
</Window>

My ShellViewModel class has a public bool property IsWaiting and when I set it to true the shadow and ring comes up and everything is disabled. When I set it to false it goes back to normal, so the binding works (I'm using Fody with the PropertyChanged addin). The only problem is that the Visibility property isn't collapsed at design time.

Is there a better way to have an overlay that works at design time?

È stato utile?

Soluzione

You can set a FallbackValue on your binding, that will Collapse it in design time

Visibility="{Binding IsWaiting, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}"

You could also make IsWaiting a DependancyProperty and set the default there, But I find this the easiest solution.

Altri suggerimenti

FallbackValue doesn't always work, i.e. if your designer is actually bound to design time data, and FallbackValue actually modifies run-time behaviour of the binding which may be less than desirable in many situations. I made a markup extension that lets designers fiddle with the UI in the designer without worrying about messing up run-time behaviour. I wrote about it here: http://www.singulink.com/CodeIndex/post/wpf-visibility-binding-with-design-time-control

It can be used like this:

<Grid Visibility="{data:Value {Binding RootObject, Converter={StaticResource NullToVisibilityConverter}}, DesignValue=Visible}">
    <TextBlock Background="Red" Text="Testing visibility" />
</Grid>

The code for ValueExtension is as follows (any updates or bug fixes will be posted to the blog so I suggest checking there for the latest version):

public class ValueExtension : MarkupExtension
{
    public object DesignValue { get; set; } = DependencyProperty.UnsetValue;

    [ConstructorArgument("value")]
    public object Value { get; set; } = DependencyProperty.UnsetValue;

    public ValueExtension() { }

    public ValueExtension(object value)
    {
        Value = value;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var provideValueTarget = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
        var property = provideValueTarget.TargetProperty as DependencyProperty;
        var target = provideValueTarget.TargetObject as DependencyObject;

        if (target == null || property == null)
           return this;

        object value = DesignerProperties.GetIsInDesignMode(target) && DesignValue != DependencyProperty.UnsetValue ? DesignValue : Value;

        if (value == DependencyProperty.UnsetValue || value == null)
            return value;

        if (value is MarkupExtension)
            return ((MarkupExtension)value).ProvideValue(serviceProvider);

        if (property.PropertyType.IsInstanceOfType(value))
            return value;

        return TypeDescriptor.GetConverter(property.PropertyType).ConvertFrom(value);
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top