15

我是一位经验丰富的 C# 开发人员,但也是 WPF 新手。我无法通过网络搜索找到答案的基本问题(我认为)。这是简化的用例...

我想在 WPF TextBlock 中显示一个字符串。所以我在我的 XAML 控件的代码隐藏中编写了一些 C# 代码......

public class MyCoolControl : UserControl
{
   public void InitializeMyCoolControl()
   {
      this.DataContext = "SomeStringOnlyAvailableAtRuntime"; // Perhaps from a database or something...
   }
}

我像这样设置我的 XAML:

<UserControl ... snip...>
   <!-- Bind the textblock to whatever's in the DataContext -->
   <TextBlock Text="{Binding}"></TextBlock>
</UserControl>

效果很好,当我执行我的应用程序时,我可以看到值“SomeStringOnlyAvailableAtRuntime”。但是,我在使用 Visual Studio 2008 的 XAML 设计器的设计时看不到任何东西。

如何在设计时查看文本块的占位符值(任何内容)?

谢谢!

-麦克风

4

5 回答 5

24

在设计用户控件时,我经常使用FallbackValue绑定来查看一些东西。例如:

<TextBlock Text={Binding Path=AverageValue, FallbackValue=99.99} />

但是,由于FallbackValue不仅仅在设计时应用,如果您FallbackValue出于其他原因想在运行时使用,这可能不合适。

于 2009-03-30T01:16:46.107 回答
2

在您的示例中,您可能需要使用TargetNullValue,而不是绑定FallbackValue表达式可能null在设计时使用。DataContextnull

FallBackValue如果Path绑定中的给定不存在,则使用,但由于没有指定路径,我假设DataContext将被评估为null.

<UserControl ... snip...>
  <!-- Bind the textblock to whatever's in the DataContext -->   
    <TextBlock Text="{Binding TargetNullValue=Nothing to see}"></TextBlock>
</UserControl>

另请注意,需要 .NET Framework 3.5 SP1,因为这两个附加属性是在 SP1 中添加的。

于 2009-03-30T14:01:25.067 回答
0

我不知道使用 Visual Studio 的编辑器执行此操作的方法,但您可以使用 Expression Blend 执行此操作。

这是描述如何实现这一目标的文章。

我确实希望 MS 将 Blend 和 Visual Studio 的功能合并在一起,因为让一个包做一件事而另一个包做另一件事有点傻。特别是当他们来自同一家公司时。

于 2009-03-29T21:21:42.477 回答
0

在这种情况下,让 MultiValueConverter 或 ViewModel 对象处理对象加载并为您更新依赖项属性不是最好的选择吗?

于 2010-03-05T09:34:12.813 回答
0

TargetNullValue和都FallbackValue在运行时具有功能,因此它们不是好的占位符选择。
TargetNullValue:如果目标属性值相等TargetNullValue,则源属性设置为null,如果源属性为null,则目标属性设置为TargetNullValue
FallbackValue:如果源Bindingnull或未能将源属性转换为目标属性,则目标属性将设置为FallbackValue

您可以创建自定义 MarkupExtension 以在设计器中显示占位符,并在运行时进行正常绑定

我的代码:

//Coding by Squirrel Downy(Flithor)
public class PlaceHolderBinding : MarkupExtension
{
    /// <summary>
    /// Show placeholder in designer, if null than ignore it
    /// </summary>
    public object PlaceHolder { get; set; }
    /// <summary>
    /// Binding works in runtime
    /// </summary>
    public BindingBase Binding { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        //if no binding
        if (Binding == null) throw new ArgumentNullException("Binding");

        //get target info
        var target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
        if (target == null) throw new InvalidOperationException("Only support as Binding");

        //get target object and check is DependencyObject
        if (!(target.TargetObject is DependencyObject targetObject))
            throw new InvalidOperationException("Only support on DependencyObject");

        //if target in designer, return placeholder
        if (DesignerProperties.GetIsInDesignMode(targetObject))
            return PlaceHolder;

        //get target property and check is DependencyProperty
        if (!(target.TargetProperty is DependencyProperty targetProp))
            throw new InvalidOperationException("Only support on DependencyProperty");

        //set binding and return binding provide value
        BindingOperations.SetBinding(targetObject, targetProp, Binding);
        return Binding.ProvideValue(serviceProvider);
    }
}
于 2021-02-24T06:27:09.713 回答