Silverlight:在分层数据模板中定义事件处理程序

3

我有一个问题,想要获取按钮的点击事件,使用的是Silverlight 3.0和匹配的Silverlight Toolkit

问题

我有这个TreeView:

TreeView sample http://a.imagehost.org/0939/TreeView.png

某个节点的值是其子节点值的总和。目前只能在叶子节点添加数据。 我想实现的是用户可以添加(并最终删除)树中的条目,以创建自定义图表。 为此,我希望“加号”可以插入一个新行/节点作为用户单击的节点的子节点。(例如,如果我在“Display”处单击加号,则会在下面得到一行,以指定CRT或TFT或其他内容。)

问题是,尽管我想了很久,但我不知道如何接收任何有用的事件。 TextBlock、TextBox和Button在分层模板中定义,我无法在该模板中定义Click处理程序。

另一方面,我还没有找到一种方法可以从(C#)代码中获取某个TreeViewItem的模板项。 我很清楚地知道可以通过trv.ItemContainerGenerator.GetContainerFromItem(item)来实现,而且正如Justin Angel展示的那样,我也可以很好地更改字体大小,但是没有找到任何访问文本框或按钮的方法。

有没有办法捕获按钮的单击事件? 或者获取提供“添加下面”功能的其他替代方法?

提前致谢。


更多数据

树形视图 XAML 如下:

<controls:TreeView x:Name="SankeyDataTree" 
    ItemTemplate="{StaticResource SankeyTreeTemplate}" BorderThickness="0" 
    Background="{x:Null}" HorizontalAlignment="Left" VerticalAlignment="Top">
    <controls:TreeViewItem IsExpanded="True">
        <controls:TreeViewItem.HeaderTemplate>
            <DataTemplate>
                <TextBlock Text="Loading..."/>
            </DataTemplate>
        </controls:TreeViewItem.HeaderTemplate>
    </controls:TreeViewItem>
</controls:TreeView>

我使用这个HierarchicalDataTemplate(并借鉴了Timmy Kokke的方法):

<Data:HierarchicalDataTemplate x:Key="SankeyTreeTemplate" ItemsSource="{Binding Children}">
    <Grid Height="24">
        <Grid.ColumnDefinitions>
            <!-- ... -->
        </Grid.ColumnDefinitions>
        <TextBlock Text="{Binding Path=Value.name, Mode=TwoWay}" VerticalAlignment="Center"/>
        <TextBox Text="{Binding Path=Value.flow, Mode=TwoWay}" Margin="4,0" VerticalAlignment="Center" d:LayoutOverrides="Width" Grid.Column="1" TextAlignment="Right" Visibility="{Binding Children, Converter={StaticResource BoxConverter}, ConverterParameter=\{box\}}"/>
        <TextBlock Text="{Binding Path=Value.throughput, Mode=TwoWay}" Margin="4,0" VerticalAlignment="Center" d:LayoutOverrides="Width" Grid.Column="1" TextAlignment="Right" Visibility="{Binding Children, Converter={StaticResource BoxConverter}, ConverterParameter=\{block\}}"/>
        <Button Margin="0" Grid.Column="2" Style="{StaticResource TreeViewItemButtonStyle}">
            <Image Source="../Assets/add.png" Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Button>
    </Grid>
</Data:HierarchicalDataTemplate>

这个TreeView绑定了一个 "SimpleTree",它的值基本上只包含一个字符串(名称)和两个双精度浮点数(流量和吞吐量)。
public String name { get; set; }
public Double flow { get; set; }
public Double throughput { get; set; }

(此外,还需要编写 INotifyPropertyChanged 的代码以实现文本框的双向绑定。)
2个回答

3

您可以在代码后台处理按钮点击事件。要访问数据,只需将其绑定到标记属性即可。

<Button Margin="0" Grid.Column="2" 
        Click="Button_Click" Tag="{Binding}"
        Style="{StaticResource     TreeViewItemButtonStyle}">            
  <Image Source="../Assets/add.png" Margin="0" 
         HorizontalAlignment="Center" VerticalAlignment="Center"/>        
</Button>

在代码后端中,处理它并访问元素。
private void Button_Click(object sender, RoutedEventArgs e)
{
   var data = ((Button)sender).Tag as SimpleTreeNode
}

这里的SimpleTreeNode是你树形元素类的名称。

现在,您应该能够向找到的数据添加新节点。


谢谢您的回复 :)这证实了我怀疑的事情;如果我在Page.xaml中有分层数据模板,它就可以工作。 如果模板位于资源字典中(也就是说,在一个完全不同的文件中),是否有任何方法将事件绑定到按钮上? (如果通过<ResourceDictionary.MergedDictionaries/>聚合到App.xaml中,我是否需要将EventHandler放置在App.xaml.cs(或适当的代码后台文件)中?) - Cornelius

3
您可以将一个Behavior附加到HierarchicalDataTemplate中的Button,并让它处理ButtonClick事件。

下载并安装Expression Blend 3 SDK。在项目中添加对System.Windows.Interactivity的引用,并添加附加到ButtonBehavior

public class ButtonClickBehavior : Behavior<Button> {

  protected override void OnAttached() {
    base.OnAttached();
    AssociatedObject.Click += ButtonClick;
  }

  protected override void OnDetaching() {
    base.OnDetaching();
    AssociatedObject.Click -= ButtonClick;
  }

  void ButtonClick(object sender, RoutedEventArgs e) {
    Node node = AssociatedObject.DataContext as Node;
    if (node != null) {
      // Button clicked. Do something to associated node.
    }
  }

}

Behavior 添加到 HierarchicalDataTemplate 中的 Button 上(假设此名称空间声明: xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"):

<Button Margin="0" Grid.Column="2" Style="{StaticResource TreeViewItemButtonStyle}">
  <Image Source="../Assets/add.png" Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
  <interactivity:Interaction.Behaviors>
    <local:ButtonClickBehavior/>
  </interactivity:Interaction.Behaviors>
</Button>

如果需要,您可以向ButtonClickBehavior添加属性,并从XAML中设置这些属性,以创建更具可重用性的Behavior


太棒了。感谢您的帮助!我知道微软会非常细致,并且有一种方法可以做到我想要的。;) - Cornelius
Node类在哪里?我需要在WPF UserControl中实现这个确切的行为,但是由于我没有Node类的命名空间引用,所以无法编译,而且谷歌也没有帮助到我。谢谢。 - Shawn
Node 类是您自己的类。它是树视图中每个节点绑定数据时绑定到的对象的类。 - Martin Liversage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接