以编程方式设置 DataTemplate 时的 WPF/Silverlight 绑定

发布于 2024-08-27 06:27:54 字数 2356 浏览 8 评论 0原文

我有我的小设计工具(我的程序)。

左侧有 TreeView,右侧有 Accordion。

当我选择一个节点时,我想根据所选节点的 DataContext 中的属性动态构建折叠项。

选择节点工作正常,当我使用此示例代码进行测试时,它也工作正常。

XAML 代码:

<layoutToolkit:Accordion x:Name="accPanel"
                         SelectionMode="ZeroOrMore"
                         SelectionSequence="Simultaneous">
  <layoutToolkit:AccordionItem Header="Controller Info">
    <StackPanel Orientation="Horizontal" DataContext="{Binding}">
      <TextBlock Text="Content:" />
      <TextBlock Text="{Binding Path=Name}" />
    </StackPanel>
  </layoutToolkit:AccordionItem>
</layoutToolkit:Accordion>

C# 代码:

private void treeSceneNode_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
   if (e.NewValue != e.OldValue)
   {
      if (e.NewValue is SceneNode)
      {
         accPanel.DataContext = e.NewValue; //e.NewValue is a class that contains Name property
      }
   }
 }

但是当我尝试使用 DateTemplate 实现此目的并动态构建 ShoulderItem 时,会出现问题,绑定不起作用:

<layoutToolkit:Accordion x:Name="accPanel"
                         SelectionMode="ZeroOrMore"
                         SelectionSequence="Simultaneous" />

并且在我的 ResourceDictionary

<DataTemplate x:Key="dtSceneNodeContent">
   <StackPanel Orientation="Horizontal" DataContext="{Binding}">
      <TextBlock Text="Content:" />
      <TextBlock Text="{Binding Path=Name}" />
   </StackPanel>
</DataTemplate>

和 C# 代码中使用 DataTemplate:

private void treeSceneNode_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
  if (e.NewValue != e.OldValue)
  {
    ResourceDictionary rd = new ResourceDictionary();
    rd.Source = new Uri("/SilverGL.GUI;component/SilverGLDesignerResourceDictionary.xaml", UriKind.RelativeOrAbsolute);

    if (e.NewValue is SceneNode)
    {
      accPanel.DataContext = e.NewValue;

      AccordionItem accController = new AccordionItem();
      accController.Header = "Controller Info";
      accController.ContentTemplate = rd["dtSceneNodeContent"] as DataTemplate;

      accPanel.Items.Add(accController);
    }
    else
    {
      // Other type of node
    }
  }
}

I have my little designer tool (my program).

On the left side I have TreeView and on the right site I have Accordion.

When I select a node I want to dynamically build Accordion Items based on Properties from DataContext of selected node.

Selecting nodes works fine, and when I use this sample code for testing it works also.

XAML code:

<layoutToolkit:Accordion x:Name="accPanel"
                         SelectionMode="ZeroOrMore"
                         SelectionSequence="Simultaneous">
  <layoutToolkit:AccordionItem Header="Controller Info">
    <StackPanel Orientation="Horizontal" DataContext="{Binding}">
      <TextBlock Text="Content:" />
      <TextBlock Text="{Binding Path=Name}" />
    </StackPanel>
  </layoutToolkit:AccordionItem>
</layoutToolkit:Accordion>

C# code:

private void treeSceneNode_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
   if (e.NewValue != e.OldValue)
   {
      if (e.NewValue is SceneNode)
      {
         accPanel.DataContext = e.NewValue; //e.NewValue is a class that contains Name property
      }
   }
 }

But the problem occurs when I'm trying to achive this using DateTemplate and dynamically build AccordingItem, the Binding is not working:

<layoutToolkit:Accordion x:Name="accPanel"
                         SelectionMode="ZeroOrMore"
                         SelectionSequence="Simultaneous" />

and DataTemplate in my ResourceDictionary

<DataTemplate x:Key="dtSceneNodeContent">
   <StackPanel Orientation="Horizontal" DataContext="{Binding}">
      <TextBlock Text="Content:" />
      <TextBlock Text="{Binding Path=Name}" />
   </StackPanel>
</DataTemplate>

and C# code:

private void treeSceneNode_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
  if (e.NewValue != e.OldValue)
  {
    ResourceDictionary rd = new ResourceDictionary();
    rd.Source = new Uri("/SilverGL.GUI;component/SilverGLDesignerResourceDictionary.xaml", UriKind.RelativeOrAbsolute);

    if (e.NewValue is SceneNode)
    {
      accPanel.DataContext = e.NewValue;

      AccordionItem accController = new AccordionItem();
      accController.Header = "Controller Info";
      accController.ContentTemplate = rd["dtSceneNodeContent"] as DataTemplate;

      accPanel.Items.Add(accController);
    }
    else
    {
      // Other type of node
    }
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

分開簡單 2024-09-03 06:27:55

你缺这个吗?

accController.Content = e.NewValue;

另外,我认为您不需要使用 DataContext="{Binding}"; DataContext 无论如何都会继承。

Are you missing this?

accController.Content = e.NewValue;

Also, I don't think you need to use DataContext="{Binding}"; the DataContext will inherit anyway.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文