100

我在没有表达式混合的情况下工作,只是在 vs2010 中使用 XAML 编辑器。抛开这个智慧不谈,我越来越看到设计时数据绑定的需求。对于简单的情况,该FallbackValue属性可以很好地工作(文本框和文本块等)。但尤其是在处理ItemsControl等时,确实需要在设计器中显示示例数据,以便您可以调整和调整控件和数据模板,而无需运行可执行文件。

我知道这ObjectDataProvider允许绑定到一个类型,因此可以提供用于可视化的设计时数据,但是有一些杂耍可以让真实的运行时数据绑定而不会通过加载加载设计时间来浪费资源,虚拟数据和运行时绑定。

我真正想要的是能够在 XAML 设计器中显示“John”、“Paul”、“George”和“Ringo”作为我的样式项ItemsControl,但在应用程序中显示真实数据运行。

我也知道 Blend 允许一些花哨的属性来定义设计时绑定数据,这些数据在运行时条件下被 WPF 有效忽略。

所以我的问题是:

1. 如何在 Visual Studio XAML 设计器中利用集合和重要数据的设计时绑定,然后顺利切换到运行时绑定?

2. 其他人是如何解决这个设计时与运行时数据的问题的?在我的情况下,我不能很容易地为两者使用相同的数据(就像一个能够使用数据库查询一样)。

3. 他们的表达式混合替代品是否可以用于数据集成的 XAML 设计?(我知道有一些替代方案,但我特别想要一些我可以使用并查看绑定样本数据等的东西?)

4

8 回答 8

121

使用 VS2010,您可以使用设计时属性(适用于 SL 和 WPF)。无论如何,我通常都有一个模拟数据源,所以这只是一个问题:

  • 添加命名空间声明

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    
  • 将模拟数据上下文添加到窗口/控件资源

    <UserControl.Resources>
      <ViewModels:MockXViewModel x:Key="DesignViewModel"/>
    </UserControl.Resources>
    
  • 设置设计时数据上下文

    <Grid d:DataContext="{Binding Source={StaticResource DesignViewModel}}" ...
    

工作得很好。

于 2011-03-20T12:28:47.280 回答
17

作为 Goran 接受的答案和 Rene 出色评论的结合。

  • 添加命名空间声明。 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

  • 从代码中引用您的设计时数据上下文。
    <Grid d:DataContext="{d:DesignInstance Type=ViewModels:MockXViewModel, IsDesignTimeCreatable=True}" ...

于 2017-04-03T12:14:10.470 回答
6

我使用这种方法通过 .NET 4.5 和 Visual Studio 2013 生成设计时数据。

我只有一个 ViewModel。视图模型有一个属性IsInDesignMode,它告诉设计模式是否处于活动状态(参见类ViewModelBase)。然后您可以在视图模型构造函数中设置您的设计时数据(如填充项目控件)。

此外,我不会在视图模型构造函数中加载真实数据,这可能会导致运行时出现问题,但为设计时设置数据应该不是问题。

public abstract class ViewModelBase
{
    public bool IsInDesignMode
    {
        get
        {
            return DesignerProperties.GetIsInDesignMode(new DependencyObject());
        }
    }
}

public class ExampleViewModel : ViewModelBase
{
    public ExampleViewModel()
    {
        if (IsInDesignMode == true)
        {
            LoadDesignTimeData();
        }
    }

    private void LoadDesignTimeData()
    {
        // Load design time data here
    }       
}
于 2015-07-24T06:26:03.053 回答
4

Karl Shifflett 描述了一种应该同样适用于 VS2008 和 VS2010 的方法:

在 WPF 和 Silverlight 项目中的 Visual Studio 2008 Cider Designer 中查看设计时数据

Laurent Bugnion 也有类似的方法,专注于 Expression Blend。它可能适用于 VS2010,但我还没有证实这一点。

在 Microsoft Expression Blend 中以设计模式模拟数据

于 2010-06-18T18:46:18.350 回答
4

也许 Visual Studio 2010 和 Expression Blend 4 的新设计时功能是您的选择。

WPF 应用程序框架 (WAF)的BookLibrary示例应用程序显示了它的工作原理。请下载 .NET4 版本。

于 2010-07-10T09:30:35.487 回答
4

类似于最高评价的答案,但在我看来更好:您可以创建一个静态属性来返回设计数据的实例并直接从 XAML 引用它,如下所示:

<d:UserControl.DataContext>
    <Binding Source="{x:Static designTimeNamespace:DesignTimeViewModels.MyViewModel}" />
</d:UserControl.DataContext>

这避免了使用UserControl.Resources. 您的静态属性可以用作工厂,允许您构造重要的数据类型 - 例如,如果您没有默认 ctor,则可以在此处调用工厂或容器以注入适当的依赖项。

于 2017-02-13T06:10:41.387 回答
4

使用 Visual Studio 2017,我一直在尝试遵循所有指南和诸如此类的问题,但我仍然面临一个<ItemsControl>根本没有执行我在DesignFooViewModel继承自FooViewModel. 我在这个“方便的”MSDN 指南(剧透:MessageBox调试)之后确认了“未执行”部分。虽然这与原始问题没有直接关系,但我希望它可以为其他人节省很多时间。

事实证明我没有做错任何事。问题是我的应用程序需要为 x64 构建。由于Visual Studio 在 2018 年仍是 32 位进程,显然无法为设计器部分旋转 64 位主机进程,因此它无法使用我的 x64 类。真正糟糕的是,在我能想到的任何日志中都找不到错误。

因此,如果您偶然发现这个问题是因为您在设计时视图模型中看到了虚假数据(例如:无论您将属性设置为什么都会<TextBlock Text="{Binding Name}"/>显示),那么原因可能是您的 x64 版本。Name如果由于依赖关系而无法将构建配置更改为 anycpu 或 x86,请考虑创建一个完全为 anycpu 且没有依赖关系(或任何依赖关系)的新项目。因此,您最终会将代码的大部分或全部从“WPF App”项目中分离出来,但将其初始化为“C# 类库”项目。

对于我正在处理的代码库,我认为这将强制以一些代码重复为代价健康地分离关注点,这可能是净积极的事情。

于 2018-07-02T14:54:45.473 回答
0

我喜欢 jbe 的建议,特别是看看他们如何在 WAF 框架示例应用程序中执行此操作 - 他们在DesignData文件夹中使用单独的模拟/示例视图模型,然后在 XAML 中有这样的一行:

mc:Ignorable="d" 
d:DataContext="{d:DesignInstance dd:MockHomeViewModel, IsDesignTimeCreatable=True}"

(其中dd指向所在的.DesignData命名空间MockHomeViewModel

它既好又简单(我喜欢!),您可以从真实的 VM 继承并只提供虚拟数据。它使事情分开,因为您不需要使用任何仅设计时的代码污染您的真实虚拟机。我很欣赏使用 IOC 等的大型项目可能看起来完全不同,但对于小型项目来说效果很好。

但正如 joonas 指出的那样,它似乎不适用于 VS2017 中的 x64 版本,而 VS2019 似乎仍然如此(我使用的是 V2019 16.6 社区版)。开始工作并不繁琐,但在进行更改(或通常情况下,进行几次更改!)后突然停止工作时可能会引起一些头疼。

对于任何尝试它的人,我建议创建一个新的简单 WPF 项目(比如一个视图、一个视图模型、一个模拟 vm)并使用它;让它工作,然后打破它。我有时发现,再多的解决方案清理和重建都无法修复它,唯一有效的方法就是关闭 VS 并重新启动,突然间我的设计时数据又回来了!

于 2020-12-31T12:39:01.897 回答