【问题标题】:Silverlight: Define event handler in hierarchical data templateSilverlight:在分层数据模板中定义事件处理程序
【发布时间】:2009-09-01 10:38:26
【问题描述】:

我在获取按钮的单击事件时遇到问题,我正在使用 Silverlight 3.0 与 Silverlight Toolkit 匹配。

问题

我有这个 TreeView:

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

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

问题是,尽管我的大脑很有价值,但我不知道如何接收任何有用的事件。 TextBlock、TextBox 和 Button 是在分层模板中定义的,我无法在该模板中定义 Click-handler。

OTOH,我还没有找到从 (c#) 代码中获取某个 TreeViewItem 的模板项的方法。很好,我能够做到 trv.ItemContainerGenerator.GetContainerFromItem(item),并且作为Justin Angel showed,我可以很好地更改字体大小,但没有找到任何访问文本框或按钮的方法。

有什么方法可以捕捉到按钮的点击事件?或者任何其他获得“添加下方”功能的方法?

提前谢谢你。


更多数据

treeview 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 的​​代码以双向绑定到文本框。)

【问题讨论】:

    标签: silverlight treeview events


    【解决方案1】:

    您可以将Behavior 附加到HierarchicalDataTemplate 中的Button,并让它处理来自Button 的Click 事件。

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

    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。

    【讨论】:

    • 太棒了。感谢您的帮助!我知道微软会很彻底,并且有办法做我想做的事。 ;)
    • Node 类在哪里?我需要 WPF UserControl 中的这种确切行为,但无法编译它,因为我没有对 Node 类的命名空间的引用,而且我的谷歌也没有帮助。谢谢。
    • Node 类是你“拥有”的类。它是树视图中每个节点使用数据绑定绑定到的对象的类。
    • 啊,现在说得通了。非常感谢。
    【解决方案2】:

    您可以在后面的代码中处理按钮单击事件。要获取数据,只需将其绑定到 Tag 属性即可。

    <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 中有分层数据模板,它就可以工作。如果模板位于资源字典中(意味着,在完全不同的文件中),有什么方法可以将事件绑定到按钮? (如果它是通过 在 App.xaml 中聚合的,我是否必须将 EventHandler 放在 App.xaml.cs(或相应的代码隐藏文件)中?)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    • 1970-01-01
    相关资源
    最近更新 更多