设计时 XAML 的默认值

Posted

技术标签:

【中文标题】设计时 XAML 的默认值【英文标题】:Default value at design time XAML 【发布时间】:2013-06-17 00:23:19 【问题描述】:

我有一个绑定的TextBlock,XAML:

<TextBlock Text="Binding MyText"/>

我知道如果绑定不可用,可以使用FallbackValue,但这发生在运行时吗?有没有办法在设计时显示默认值?如果我在设计我的窗口时能看到一个值而不是空的TextBlock,那会更容易。

谢谢

【问题讨论】:

您可以设置一个虚拟 ViewModel 作为数据上下文,它应该将 MyText 属性初始化为某些东西。 How to see design-time data-binding in XAML editor (it works in runtime)?的可能重复 【参考方案1】:

更新:Visual Studio 2019 v16.7

您现在可以这样做:

<TextBlock Text="Binding MyText" d:Text="Design time value"/>

如果您更喜欢Ian Bamforth's answer 的简洁版本,您可以这样做

<TextBlock Text="Binding MyText, FallbackValue=None"/>

【讨论】:

有没有办法只做设计时的后备值? -- 如果我的视图模型中的属性为空,我不希望这些值显示出来。 我怀疑您需要一个适当的设计时视图模型来完全处理这种情况。但是,如果您特别担心现有属性的值为 null,您可以使用 TargetNullValue 属性来指出它。 d:Text 听起来不错,但目前仅限于“WPF .NET Core 和 UWP 项目” @jvcleave:他们引入了一个修复程序。此功能也可用于预览频道中的 .NET Framework。要启用它,请转到工具 > 选项 > 环境 > 预览功能,选择适用于 .NET Framework 的新 WPF XAML 设计器,然后重新启动 Visual Studio。【参考方案2】:

改编自this 问题的示例。

这对我有用 - 文本“无”显示在设计器中:

 <TextBlock>
    <TextBlock.Text>
        <Binding ElementName="root" Path="blah" FallbackValue="None" />
    </TextBlock.Text>
</TextBlock>

希望有帮助

【讨论】:

你能解释一下吗?也许我遗漏了一些东西,但这显示了如何在 Margin 属性上设置 FallBackValue ...? 我对此投了反对票,因为 FallbackValue 是无法解析绑定时显示的值。如果您在 XAML 中指定 datacontext(或 datacontexttype),则此解决方案不起作用,因为可以成功解析绑定(在我的情况下,元素已折叠,我不希望在设计时这样做)【参考方案3】:

使用FallbackValue 是错误的,因为它还会影响运行时行为(如果绑定无法从源获取值,则使用回退值)。

我想出了一个模仿Binding 的自定义标记扩展(理想情况下,我宁愿继承Binding,但ProvideValue 方法不是虚拟的...):

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;

namespace MyNamespace

    public class BindingEx : MarkupExtension
    
        private readonly Binding _binding;

        public BindingEx()
        
            _binding = new Binding();
        

        public BindingEx(string path)
        
            _binding = new Binding(path);
        

        public PropertyPath Path
        
            get => _binding.Path;
            set => _binding.Path = value;
        

        public BindingMode Mode
        
            get => _binding.Mode;
            set => _binding.Mode = value;
        

        public RelativeSource RelativeSource
        
            get => _binding.RelativeSource;
            set => _binding.RelativeSource = value;
        

        public string ElementName
        
            get => _binding.ElementName;
            set => _binding.ElementName = value;
        

        public IValueConverter Converter
        
            get => _binding.Converter;
            set => _binding.Converter = value;
        

        public object DesignValue  get; set; 

        public override object ProvideValue(IServiceProvider serviceProvider)
        
            var target = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
            if (target.TargetObject is DependencyObject d && DesignerProperties.GetIsInDesignMode(d))
                return DesignValue;

            return _binding.ProvideValue(serviceProvider);
        
    

您可以像 Binding 一样使用它,并添加 DesignValue 属性:

<TextBlock Text="my:BindingEx Name, DesignValue=John Doe" />

请注意,BindingEx 没有 Binding 的所有属性,但如果需要,您可以轻松添加它们。

【讨论】:

这太棒了!【参考方案4】:

如果您已绑定此数据并且正在使用 MVVM 架构,则为其绑定的模型项设置默认值将在设计时显示该值

我只是在使用:

模型.cs:

private int frame = 999999;
public int Frame

  get  return frame; 
  set
  
    frame = value;
    NotifyPropertyChanged(m => m.Frame);
  

在我的 XAML 中:

 <TextBlock Text="Binding Path=Frame"  />

默认值“999999”显示在设计器中

【讨论】:

以上是关于设计时 XAML 的默认值的主要内容,如果未能解决你的问题,请参考以下文章

如何在VS2010 WPF设计器中控制自定义控件的默认属性

在设计时重置已发布的属性默认值

RESTful API 设计:url 参数应该有默认值吗?

Xamarin.Forms:有没有办法在xaml中设置派生样式的默认字体(系列)?

清除网站设计时的默认值

组件的默认属性值