2

我想在 XAML 中编写POCO,并使用 DataTemplate 在运行时在 GUI 中显示该对象。到目前为止,一切都很好; 我知道该怎么做。

由于我已经有一个可以将我的 POCO 转换为 WPF 可视化树的 DataTemplate,有没有办法让 Visual Studio 设计器一起玩,并让设计视图在我编辑时向我显示 POCO+DataTemplate 的结果 GUI POCO 的 XAML?(显然设计师不知道如何编辑“设计视图”;我不希望工具箱或单击并拖动在设计表面上工作。这很好 - 我只想看到预览,因为我编辑。)

如果您好奇,所讨论的 POCO 将是游戏的关卡地图。(此时,我不打算发布最终用户地图编辑器,因此我将在 Visual Studio 中自己进行所有编辑。)所以 XAML 不是像 Window 和 UserControl 这样的 WPF GUI 对象,但它是仍然不是我想盲目地敲出一些 XAML 并希望最好的东西。我想看看我在做什么(GUI 地图)。

如果我尝试创建一个根是我的地图对象的 XAML 文件,设计器会显示“故意留空 - 可视化设计器不支持文档根元素”。即使我在 App.xaml 中定义了 DataTemplate,它也会这样做<Application.Resources>

但我知道设计师可以在我的 POCO 位于 WPF 对象中时展示它。实现我想要的一种可能的方法是拥有一个仅包含 ContentPresenter 的 ScratchUserControl,并在该 ContentPresenter 的 Content 属性中编写我的 POCO XAML,例如:

<UserControl ...>
    <ContentPresenter>
        <ContentPresenter.Content>
            <Maps:Map .../>
        </ContentPresenter.Content>
    </ContentPresenter>
</UserControl>

但是当我完成编辑时,我必须确保将内容复制回自己的文件中,这看起来很乏味且容易出错,而且我不喜欢乏味且容易出错。既然我可以通过这种方式预览我的 XAML,那么没有 UserControl 就没有办法吗?

4

2 回答 2

2

事实上,我现在正在这样做。创建一个 ResourceDictionary 并从其他 XAML 文件中引用它。例如,制作一个包含普通旧对象的文件,即:

<Windows:ResourceDictionary>
  <Collections:ArrayList x:Key="PreferenceList">
    <NumericPreference id="server.port"
     helpText="The port on which the server should listen for incoming connections (default is 30588)"
     min="1"
     max="65535"
     step="1"
     displayName="Port"
     validationName="Port number" />
  </Collections:ArrayList>
</Windows:ResourceDictionary>

(其中 NumericPreference 被您的 POCO 替换),然后像这样引用它:

<UserControl>
  <UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Preferences.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </UserControl.Resources>
  <Grid>
    <!-- Your code here -->
  </Grid>
</UserControl>

...但是,是的,您仍然需要将“临时用户控件”连接到它以查看设计器结果,但不涉及复制和粘贴。这里的关键部分是 ResourceDictionary Source="YourStaticResource.xaml"

您不能将地图作为根元素(根元素必须是 ResourceDictionary),但可以将其作为 ResourceDictionary 的唯一子元素。

要引用资源,当然可以使用 {StaticResource XXX} 或 {DynamicResource XXX},其中 XXX 是您在其 XML 文件中为 POCO 提供的 x:Key(在这种情况下,我提供了引用的 POCO 对象、ArrayList、“PreferenceList “ 钥匙)

于 2009-08-11T03:37:07.593 回答
0

我相当肯定你不会在这里得到你想要的。

WPF 不会在设计窗口中以逻辑方式处理太多。这包括(大部分)您在 XAML 数据绑定中使用的 DataTemplate 和 IValueConverter 对象,因为这些对象通常与在运行时才实例化的 (POCO) 对象一起使用。

这可以解释为什么它在 UserControl 示例中有效,因为您清楚地在 XAML 中创建了 Map POCO 的实例。设计器窗口绝对不会尝试呈现基于绑定或模板的任何内容,这些绑定或模板引用了 Visual Studio 在设计时无法实例化的对象。这基本上意味着如果您尝试在幕后的 C#(或其他)代码中创建这些对象,则不能让您的对象显示在设计窗口中。您的后端代码不能由设计窗口运行,因为它必须由编译器构建并运行,然后才能执行。(以前版本的 Visual Studio 使用极端的变通方法来尝试解决这个问题,微软不再提供这种支持。)像 XAML 这样的标记语言不'

简而言之,我不认为 XAML 设计窗口曾经打算以您尝试使用它的方式使用。

如果您真的希望能够在设计器中看到您的 POCO,但您不想将其插入到带有 ContentPresenter 的 UserControl 中 --- 尝试从设计器可以呈现的适当根元素中派生您的 POCO , 并添加一个 Serialize 方法来读取/写入文件。

如果这些解决方案对您不起作用,那么您可能不得不处理 Visual Studio 未在设计窗口中呈现 Map 对象的问题。也许这最终会给您一些创建独立地图编辑器的动力,即使您没有将其发送给最终用户。您可能想花时间编写一个简单的编辑器,即使它仅供您使用。Visual Studio 不会取代您的自定义地图编辑器 - 至少不会以任何对您有用的方式。

于 2009-06-30T00:31:10.290 回答