绑定元素对ViewModel属性的可见性,具有设计时支持

时间:2012-12-06 04:39:48

标签: wpf caliburn.micro fody-propertychanged

我使用Caliburn.Micro获得了一个WPF应用程序。当我希望应用程序等待在后台完成某些工作时,我希望能够使用阴影和进度环(来自MahApps.Metro)覆盖应用程序。

我目前所拥有的功能确实有效,但叠加层在设计时始终处于开启状态。我的ShellView窗口如下所示:

<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>

我的ShellViewModel课程有一个公共bool属性IsWaiting,当我将其设置为true时,阴影和铃声就出现了,一切都被禁用了。当我将其设置为false时,它会恢复正常,因此绑定有效(我正在使用带有PropertyChanged插件的Fody)。唯一的问题是Visibility属性在设计时没有折叠。

有没有更好的方法让叠加层在设计时有效?

2 个答案:

答案 0 :(得分:7)

您可以在绑定上设置FallbackValue,在设计时Collapse

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

您也可以将IsWaiting设为DependancyProperty并设置默认值,但我发现这是最简单的解决方案。

答案 1 :(得分:2)

FallbackValue并不总是有效,即如果你的设计师实际上绑定了设计时间数据,并且FallbackValue实际上修改了绑定的运行时行为,这在许多情况下可能不太理想。我做了一个标记扩展,让设计师在设计器中摆弄UI,而不用担心弄乱运行时行为。我在这里写到:http://www.singulink.com/CodeIndex/post/wpf-visibility-binding-with-design-time-control

可以像这样使用:

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

ValueExtension的代码如下(任何更新或错误修复都将发布到博客,所以我建议在那里查看最新版本):

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);
    }
}