在WPF中,有哪些方法可用于虚拟设计时数据?

在WPF中,有哪些方法可用于虚拟设计时数据?,wpf,data-binding,xaml,designer,design-time,Wpf,Data Binding,Xaml,Designer,Design Time,我没有使用expression blend,只是在vs2010中使用XAML编辑器。撇开这一点不谈,我越来越意识到设计时数据绑定的必要性。对于简单的情况,FallbackValue属性工作得非常好(文本框和文本块等)。但特别是在处理ItemsControl等时,确实需要在设计器中显示示例数据,以便您可以调整和调整控件和数据模板,而无需运行可执行文件 我知道ObjectDataProvider允许绑定到类型,因此可以提供用于可视化的设计时数据,但是通过加载设计时、模拟数据和运行时绑定,允许真实的运

我没有使用expression blend,只是在vs2010中使用XAML编辑器。撇开这一点不谈,我越来越意识到设计时数据绑定的必要性。对于简单的情况,
FallbackValue
属性工作得非常好(文本框和文本块等)。但特别是在处理
ItemsControl
等时,确实需要在设计器中显示示例数据,以便您可以调整和调整控件和数据模板,而无需运行可执行文件

我知道
ObjectDataProvider
允许绑定到类型,因此可以提供用于可视化的设计时数据,但是通过加载设计时、模拟数据和运行时绑定,允许真实的运行时数据绑定,而不浪费资源

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

我还知道Blend允许使用一些奇特的属性来定义WPF在运行时条件下有效忽略的设计时绑定数据

因此,我的问题是:

1。如何利用visual studio XAML设计器中集合和非平凡数据的设计时绑定,然后顺利切换到运行时绑定?

2。其他人是如何解决这个设计时与运行时数据的问题的?在我的例子中,我不能很容易地将相同的数据用于这两种情况(比如说,数据库查询)


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

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

Laurent Bugnon也有类似的方法,专注于表达式混合。它可能适用于VS2010,但我还没有证实这一点


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

它的工作原理显示在BookLibrary示例应用程序中。请下载.NET4版本。

使用您可以使用的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}}" ...
    

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

    我只有一个模型。 视图模型有一个属性<代码>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
        }       
    }
    

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

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

    这样就不需要使用
    UserControl.Resources
    。您的静态属性可以作为一个工厂,允许您构造非平凡的数据类型-例如,如果您没有默认的ctor,您可以在此处调用工厂或容器以注入适当的依赖项。

    作为Goran的公认答案和Rene的优秀评论的混合体

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

    • 从代码中引用设计时数据上下文。

      使用Visual Studio 2017,我一直在尝试遵循所有的指南和类似的问题,我仍然面临一个
      ,它根本没有执行我在继承自
      FooViewModel
      DesignFooViewModel
      的构造函数中的代码。我确认了下面的“未执行”部分(扰流板:
      MessageBox
      调试)。虽然这与原来的问题没有直接关系,但我希望它能为其他人节省很多时间

      原来我没做错什么。问题是我的应用程序需要为x64构建。由于和显然不能为设计器部分旋转64位主机进程,因此它不能使用我的x64类。真正糟糕的是,在我能想到的任何日志中都找不到错误

      因此,如果您偶然发现这个问题,因为您在设计时视图模型中看到虚假数据(例如:
      显示
      Name
      ,无论您将属性设置为),那么原因可能是您的x64版本。如果由于依赖性而无法将构建配置更改为任意CPU或X86,请考虑创建完全为任意CPU且不具有依赖性(或任何依赖性)的新项目。因此,您最终将代码的大部分或全部(除了初始化部分)从“WPF应用程序”项目拆分为“C#类库”项目


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

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

      mc:Ignorable="d" 
      d:DataContext="{d:DesignInstance dd:MockHomeViewModel, IsDesignTimeCreatable=True}"
      
      (其中
      dd
      指向
      .DesignData
      命名空间,其中
      MockHome