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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1889966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:19:09  来源:igfitidea点击:

What approaches are available to dummy design-time data in WPF?

wpfdata-bindingxamldesignerdesign-time

提问by el2iot2

I am working without expression blend and just using the XAML editor in vs2010. The wisdom of this aside, I am increasingly seeing a need for design-time data binding. For simple cases, the FallbackValueproperty works very nicely (Textboxes and TextBlocks, etc). But especially when dealing with ItemsControland the like, one really needs sample data to be visible in the designer so that you can adjust and tweak controls and data templates without having to run the executable.

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

I know that ObjectDataProviderallows for binding to a type, and thus can provide design-time data for visualizing, but then there is some juggling to allow for the real, run-time data to bind without wasting resources by loading loading both the design time, dummied data and the runtime bindings.

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

Really what I am wanting is the ability to have, say, "John", "Paul", "George", and "Ringo" show up in the XAML designer as stylable items in my ItemsControl, but have real data show up when the application runs.

我真正想要的是能够让“John”、“Paul”、“George”和“Ringo”在 XAML 设计器中显示为我的ItemsControl.运行。

I also know that Blend allows for some fancy attributes that define design time binding data that are effectively ignored by WPF in run-time conditions.

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

So my questions are:

所以我的问题是:

1. How might I leverage design-time bindings of collections and non-trivial data in the visual studio XAML designer and then swap to runtime bindings smoothly?

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

2. How have others solved this design-time vs. runtime data problem?In my case, i cannot very easily use the same data for both (as one would be able to with, say, a database query).

2. 其他人是如何解决设计时与运行时数据问题的?就我而言,我不能很容易地为两者使用相同的数据(因为可以使用数据库查询)。

3. Are their alternatives to expression blend that i could use for data-integrated XAML design?(I know there are some alternatives, but I specifically want something I can use and see bound sample data, etc?)

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

回答by Goran

Using VS2010 you can use Design-Time attributes(works for both SL and WPF). I usually have a mock data-source anyway so it's just a matter of:

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

  • Adding the namespace declaration

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    
  • Adding the mock data context to window/control resources

    <UserControl.Resources>
      <ViewModels:MockXViewModel x:Key="DesignViewModel"/>
    </UserControl.Resources>
    
  • Setting design-time data context

    <Grid d:DataContext="{Binding Source={StaticResource DesignViewModel}}" ...
    
  • 添加命名空间声明

    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}}" ...
    

Works well enough.

工作得很好。

回答by John Stritenberger

As an amalgam of Goran's accepted answer and Rene's excellent comment.

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

  • Add the namespace declaration. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

  • Reference your design time data context from code.
    <Grid d:DataContext="{d:DesignInstance Type=ViewModels:MockXViewModel, IsDesignTimeCreatable=True}" ...

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

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

回答by joonas

Using Visual Studio 2017 I have been trying to follow all of the guides and questions such as this and I was still facing a <ItemsControl>which simply did not execute the code I had inside the constructor of a DesignFooViewModelwhich inherits from FooViewModel. I confirmed the "did not execute" part following this "handy" MSDN guide(spoiler: MessageBoxdebugging). While this is not directly related to the original question, I hope it will save others a lot of time.

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

Turns out I was doing nothing wrong. The issue was that my application needs to be built for x64. As the Visual Studio is still in 2018 a 32-bit processand apparently cannot spin a 64-bit host process for the designer part it cannot use my x64 classes. The really bad thing is that there are no errors to be found in any log I could think of.

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

So if you stumble upon this question because you are seeing bogus data in with your design time view model (for example: <TextBlock Text="{Binding Name}"/>shows up Nameno matter you set the property to) the cause is likely to be your x64 build. If you are unable to change your build configuration to anycpu or x86 because of dependencies, consider creating a new project which is fully anycpu and does not have the dependencies (or any dependencies). So you end up splitting most or all but the initialization parts of the code away from your "WPF App" project into a "C# class library" project.

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

For the codebase I am working on I think this will force healthy separation of concerns at the cost of some code duplication which is probably net positive thing.

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

回答by dthrasher

Karl Shifflett describes an approach that ought to work equally well for VS2008 and VS2010:

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

Viewing Design Time Data in Visual Studio 2008 Cider Designer in WPF and Silverlight Projects

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

Laurent Bugnion has a similar approach that focuses on Expression Blend. It mightwork for VS2010, but I haven't confirmed this yet.

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

Simulating data in design mode in Microsoft Expression Blend

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

回答by jbe

Maybe the new design-time features of Visual Studio 2010 and Expression Blend 4 are an option for you.

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

How it works is shown in the BookLibrarysample application of the WPF Application Framework (WAF). Please download the .NET4 version.

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

回答by Martin

I use this approach for generating design time data with .NET 4.5 and Visual Studio 2013.

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

I have just one ViewModel. The view model has a property IsInDesignModewhich tells whether design mode is active or not (see class ViewModelBase). Then you can set up your design time data (like filling an items control) in the view models constructor.

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

Besides, I would not load real data in the view models constructor, this may lead to issues at runtime, but setting up data for design time should not be a problem.

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

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
    }       
}

回答by Hyman Ukleja

Similar to the top rated answer, but better in my opinion: You can create a static property to return an instance of design data and reference it directly from XAML like so:

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

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

This avoids the need to use UserControl.Resources. Your static property can function as a factory allowing you to construct non-trivial data types - for example if you do not have a default ctor, you can call a factory or container here to inject in appropriate dependencies.

This avoids the need to use UserControl.Resources. Your static property can function as a factory allowing you to construct non-trivial data types - for example if you do not have a default ctor, you can call a factory or container here to inject in appropriate dependencies.