【问题标题】:Xaml - How to inject a Canvas StaticResource into a DataTemplateXaml - 如何将 Canvas StaticResource 注入 DataTemplate
【发布时间】:2014-06-04 21:10:17
【问题描述】:

在 Windows Phone 8 上,我有一些画布项 StaticResources,我想将它们注入到 DataTemplate 中,但不知道该怎么做。

谁能指出我正确的方向?到目前为止,这是我的 XAML 的精简版:

<phone:PhoneApplicationPage.Resources>

    <Canvas x:Key="Item1">
        ...
    </Canvas>

    <Canvas x:Key="Item2">
        ...
    </Canvas>

    <DataTemplate x:Key="SomeTemplate">
        <StackPanel Grid.Row="0" Orientation="Horizontal">
            <Viewbox Height="96" Width="96" Margin="0,12,12,0">
                <ContentControl Content="{StaticResource Item1}" />
            </Viewbox>
        </StackPanel>
    </DataTemplate>

</phone:PhoneApplicationPage.Resources>

运行时出现未处理的异常: “调用 COM 组件时返回了错误 HRESULT E_FAIL。”

【问题讨论】:

    标签: wpf xaml windows-phone-8 windows-phone


    【解决方案1】:

    您不能将控件作为资源。一个 UI 元素不能同时位于可视化树的两个位置,因此将控件作为资源毫无意义。

    这是一个想法,但如果您大量使用这些资源,我不确定它会如何执行。我很快测试了它,它似乎可以工作,但我没有真正使用它,所以在某些情况下可能会出现一些问题。

    1. 像这样将资源中的 Canvas 包装在 DataTemplate 中:

      <DataTemplate x:Key="Item1">
          <Canvas>
              ...
          </Canvas>
      </DataTemplate>
      
    2. 将此模板用于 ContentControl 的 ContentTemplate 属性,如下所示:

      <DataTemplate x:Key="SomeTemplate">
          ...
             <ContentControl ContentTemplate="{StaticResource Item1}" />
          ...
      </DataTemplate>
      

    希望这会有所帮助! :)

    【讨论】:

    • @Gavin 嗯,这很奇怪。它对我来说工作得很好,我用一个相当复杂的 Canvas 进行了测试。无论如何,我看到您找到了适合您的解决方案,这很重要。 :) 如果您希望我检查为什么我的建议不起作用,您可以共享您尝试过的 Canvas 的代码(通过编辑您的答案或在 cmets 中提供指向 pastebin 的链接)。
    • @Gavin 在测试我的想法时,您不可能更改 ContentControl 的样式(如 Sheridan 建议的那样(顺便说一句)),对吧?如果不是,它应该准确地显示您想要的画布上的内容(可能不是预期的大小)。
    • @Gavin 我确实在 WP8.0 应用程序中对其进行了测试,并且运行良好。我是否遗漏了某些东西,或者 Canvases 不在我建议的 DataTemplate 中?我的想法基本上是这样的:制作一个带有 Canvas 的 DataTemplate,然后将该 DataTemplate 设置为 ContentControl 的 ContentTemplate。这是你尝试过的吗?
    • @Gavin 我可以从 pastebin 中看到您没有在画布周围放置 DataTemplate。看看这个:pastebin。这在 WP8.0 应用程序中对我有用。您也可以将 Viewbox 放在 DataTemplate 中,因此无论您在哪里使用它,您都只需指定 ContentControl 的大小。哦,很抱歉打扰您,我只是认为我的解决方案是一个很好的解决方案(比其他解决方案短),它会帮助人们。
    • @Gavin 哈哈,好吧,有时每个人都会遇到这种情况,没问题。很高兴我能提供帮助,并且您发现我的解决方案是一个很好的解决方案。 :) 哦,这个应用看起来不错,祝你好运! :)
    【解决方案2】:

    您似乎对 WPF 的工作原理有些困惑。您不能将资源中的Canvas 控件注入到 XAML。您可以做的最好的事情是为您的Canvas 创建一个Style,然后将该Style 应用到您的XAML 中的一个新Canvas。但是,需要注意的是,您不能从 Style 设置 Canvas.Children 属性...这会导致错误:

    <Style TargetType="{x:Type Canvas}">
        <Setter Property="Children">
            <Setter.Value>
                <Button Content="Click me!!" />
            </Setter.Value>
        </Setter>
    </Style>
    

    但是,可以在Style 中“预定义”控件,但您必须使用ContentControl 来显示它。试试这个:

    <Style TargetType="{x:Type ContentControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ContentControl}">
                    <Canvas>
                        <Button Content="Click me!!" />
                    </Canvas>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    现在,每当您使用此 XAML 时,您都可以在 Canvas 中看到 Button

    <ContentControl />
    

    【讨论】:

      【解决方案3】:

      试试这个:

          <Grid>
              <Canvas Margin="10" Background="AliceBlue">
                  <ItemsControl ItemsSource="{Binding}">
                      <ItemsControl.ItemTemplate>
                          <DataTemplate>
                              <Canvas>
                                  <TextBlock Canvas.Left="{Binding Left}" Canvas.Top="{Binding Top}" Text="{Binding Text}" Width="50" Height="20" Foreground="Black"/>
                              </Canvas>
                          </DataTemplate>
                      </ItemsControl.ItemTemplate>
                  </ItemsControl>
              </Canvas>
          </Grid>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-30
        • 2023-03-08
        • 1970-01-01
        • 2011-08-16
        • 1970-01-01
        • 2016-10-28
        • 2013-04-28
        相关资源
        最近更新 更多