【问题标题】:Disable binding to static property during design-time在设计时禁用与静态属性的绑定
【发布时间】:2016-06-24 10:33:21
【问题描述】:

我喜欢尽可能绑定到静态属性(例如,当不需要通知或模型为其他目的实现 INotifyPropertyChanged 时),例如:

Visibility="{Binding IsAdministractor, Source={x:Static local:User.Current}, Converter={local:FalseToCollapsedConverter}}"

问题是这样的评估也在设计时起作用,因此很难与设计师合作。

普通绑定在设计时不起作用,我可以使用FallbackValue 来指定仅设计时的值(我从未在运行时使用过FallbackValue)。

有没有一种简单的方法可以在设计时使绑定到静态属性无效(禁用它们)?

我可以暂时重命名属性,例如IsAdministrator123,但这很乏味。

【问题讨论】:

  • 如果您创建 DataContext 或使用 DesignInstance 值,则普通绑定在设计时工作。这通常会使编码更容易(IntellisSense 工作、即时预览等)
  • @ASh,我同意你可以做到,但这太费力了。在任何情况下,我都不希望设计师向我展示运行时的外观,我可以简单地运行该软件。不确定“正常绑定在设计时不起作用”有多不寻常。

标签: c# wpf binding static-members xaml-designer


【解决方案1】:

您可以在转换器或静态CurrentIsAdministractor(这里是错字?)属性中check if you're in design mode,然后返回您希望看到的任何状态。

编辑:

这是一些标记扩展的代码(未经测试)

public class BindingWithDesignSupport : MarkupExtension
{
    public BindingWithDesignSupport(){}

    public BindingWithDesignSupport(BindingBase binding)
    {
        Binding = binding;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return DesignerProperties.GetIsInDesignMode(new DependencyObject()) ? DesignTimeValue : Binding.ProvideValue(serviceProvider);
    }

    public BindingBase Binding { get; set; }

    public object DesignTimeValue { get; set; }
}

你应该可以像这样使用它:

Visibility="{BindingWithDesignSupport {Binding IsAdministractor, Source={x:Static local:User.Current}, Converter={local:FalseToCollapsedConverter}},DesignTimeValue=Visibility.Visible}"

【讨论】:

  • 在这种情况下使用转换器是个好主意,没有考虑过。但是没有转换器的绑定呢?我不想将样板代码添加到每个公共静态属性 getter。
  • 嗯,某处您必须添加样板代码...关于没有转换器的绑定?您可以为这些添加转换器。此转换器通常会返回未更改的值并检查是否处于设计模式并返回 null 或其转换器参数或您喜欢的任何值。
  • 对“我喜欢尽可能绑定静态属性”的另一条评论——这可能不是最佳实践……只是一个建议:使用像 caliburn.micro 这样的 MVVM 框架。它简化了很多。
  • 在设计时使用任何其他转换器返回无效输入之前添加到 xaml 中的甜美、可链接转换器。听起来像是一个解决方案。
  • hmm,如果你想走得那么远,实际上使用 MarkupExtension 可能比使用转换器更好,因为转换器会增加绑定的计算时间,而 MarkupExtension 将是一次性的.
【解决方案2】:

可以将转换器附加到所有此类属性,这些属性具有FallbackValue(用于设计时)和Converter(用于提供运行时转换器)属性:

public class RuntimeConverter : MarkupExtension, IValueConverter
{
    public object FallbackValue { get; set; }
    public IValueConverter Converter { get; set; }

    public RuntimeConverter() { }

    public override object ProvideValue(IServiceProvider serviceProvider) => this;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
            return FallbackValue;
        if (Converter == null)
            return value;
        return Converter.Convert(value, targetType, parameter, culture);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
            return FallbackValue;
        if (Converter == null)
            return value;
        return Converter.ConvertBack(value, targetType, parameter, culture);
    }
}

那么在设计时可以改变静态属性返回的值:

<!-- split in multiple lines for readability -->
Visibility="{Binding IsPowerUser, Source={x:Static local:User.Logged},
    Converter={local:RuntimeConverter Converter={local:FalseToCollapsedConverter},
    FallbackValue=Collapsed}}">

【讨论】:

    【解决方案3】:

    您可以使用设计时数据将设计时视图模型置于您想要设计的状态。

    或者对于简单的属性,您可以在视图模型中使用所需的设计时间值来初始化它们,例如

        public bool IsAdministractor { get; set; } = true;
    

    【讨论】:

    • 你想念static
    猜你喜欢
    • 1970-01-01
    • 2014-09-10
    • 2010-10-30
    • 2019-11-15
    • 2014-04-05
    • 1970-01-01
    • 2021-08-26
    • 2014-06-29
    相关资源
    最近更新 更多