Wpf 使用XAML+;设计器是否编辑普通的旧CLR对象?

Wpf 使用XAML+;设计器是否编辑普通的旧CLR对象?,wpf,xaml,poco,Wpf,Xaml,Poco,我想在XAML中编写一个对象,并在运行时使用DataTemplate在GUI中显示该对象。到目前为止,一切顺利;我知道怎么做 既然我已经有了一个数据模板,可以将我的POCO转换为WPF可视化树,那么有没有办法让visual Studio designer配合使用,并且在我编辑POCO的XAML时,让Design视图向我显示POCO+数据模板的结果GUI?(显然,设计师不知道如何编辑“设计视图”);我不希望工具箱或单击并拖动在设计图面上工作。没关系——我只想在编辑时看到预览。) 如果你好奇的话,这

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

既然我已经有了一个数据模板,可以将我的POCO转换为WPF可视化树,那么有没有办法让visual Studio designer配合使用,并且在我编辑POCO的XAML时,让Design视图向我显示POCO+数据模板的结果GUI?(显然,设计师不知道如何编辑“设计视图”);我不希望工具箱或单击并拖动在设计图面上工作。没关系——我只想在编辑时看到预览。)

如果你好奇的话,这些POCO就是游戏的关卡地图。(在这一点上,我不打算推出最终用户地图编辑器,所以我将在Visual Studio中自己进行所有编辑。)因此,XAML不是WPF GUI对象,如Window和UserControl,但它仍然不是我想要盲目地使用一些XAML并希望得到最好的结果的东西。我想看到我正在做什么(GUI地图),因为我正在做它

如果我试图创建一个根为映射对象的XAML文件,设计器会显示“故意留空-可视化设计器不支持文档根元素”。即使我在App.XAML的
中定义了数据模板,它也会这样做

但我知道设计师可以在WPF对象中显示我的POCO。实现我想要的一种可能的方法是使用一个只包含ContentPresenter的ScratchUserControl,并在该ContentPresenter的Content属性中写入我的POCO XAML,例如:

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


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

我很确定,在这里你不会得到你想要的东西

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

这可以解释为什么它在UserControl示例中工作,因为您显然正在XAML中创建Map POCO的实例。设计器窗口绝对不会尝试呈现任何基于绑定或模板的内容,这些绑定或模板引用了Visual Studio在设计时无法实例化的对象。这基本上意味着,如果您试图在幕后的C#(或其他)代码中创建对象,则无法在设计窗口中显示这些对象。后端代码不能由设计窗口运行,因为它必须由编译器生成并运行,然后才能执行。(VisualStudio的早期版本使用极端变通方法来尝试解决此问题,Microsoft不再提供此支持。)像XAML这样的标记语言没有此限制,因为它们不包含逻辑执行序列,因此设计窗口可以仅使用解析的XAML标记在屏幕上呈现它们

简而言之,我认为XAML设计窗口从来没有打算以您试图使用它的方式使用

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


如果这些解决方案不适用于您,那么您可能必须处理Visual Studio不在设计窗口中渲染地图对象的问题。也许这会给你一些动力去创建一个独立的地图编辑器,即使你没有把它发送给最终用户。您可能想花时间编写一个简单的编辑器,即使它只供您使用。Visual Studio不会取代您的自定义地图编辑器-至少,不会以任何方式对您有用。

事实上,我现在正在这样做。创建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>

(其中数字首选项由您的POCO代替),然后参照如下:

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

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

不能将映射作为根元素(根元素必须是ResourceDictionary),但可以将其作为ResourceDictionary的唯一子元素


要引用资源,当然要使用{StaticResource XXX}或{DynamicResource XXX},其中XXX是您在其XML文件中为POCO提供的x:键(在本例中,我提供了被引用的POCO对象、ArrayList和“PreferenceList”键)

我并不是说在C#中创建映射。我说的是将它作为XAML根元素,在这种情况下,我将在XAML中创建它,就像在UserControl示例中一样清楚。没有理由VS无法使用App.xaml数据模板呈现它。它似乎明确地禁用了这个场景,我希望有人知道如何解决这个问题。我个人不希望设计窗口在任何类型的DataTemplate下呈现任何内容,尽管我承认我对它们了解不够,不能肯定这是没有办法的。我希望我能给你更可靠的建议,但恐怕我只有这些了。很遗憾没有更多的人回答XAML问题…我希望能够