【问题标题】:Silverlight treeview control selecting the last node and finding the parent?Silverlight 树视图控件选择最后一个节点并找到父节点?
【发布时间】:2012-03-19 18:24:56
【问题描述】:

如果我创建了一个 silverlight 应用程序并使用带有 HierarchicalDataTemplate 的 Treeview 控件,其父节点然后是父节点下的子节点,然后是第一个子节点下的另一个子节点。 如果我单击最后一个子节点,我如何才能将路径返回到父节点?

  • 父母

      Child1
      Child2
             ChildA
      Child3
    

因此,如果我有这个树视图并单击“ChildA”,是否有办法显示路径是 Parent-Child2-ChildA 谢谢

【问题讨论】:

  • 可以,但没那么容易。您应该将树视图绑定到视图模型列表,并且每个视图模型都应该具有 IsSelected 属性和 ParentViewModel 属性。你应该用这种方式重写你的应用程序。
  • 查看 Silverlight 控件工具包中的 TreeViewExtensions 或此处提到的 Justin Angel 的扩展:blogs.silverlight.net/blogs/justinangel/archive/2009/05/19/…
  • 由于 WPF 显然不太关心育儿问题(孩子不应该知道它是父母,但父母应该知道它是孩子),我建议您是否可以自己给课程 Parent属性,甚至可以是一个对象,这将是“最干净”的解决方案。

标签: silverlight


【解决方案1】:

马特...我相信,如果您有正确的父子链接(正如您在问题中提到的那样),然后在每次使用单击树的任何节点时使用递归调用,那么这应该符合您的目的。你可以试试下面的逻辑。

用户体验-

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"  x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <sdk:TreeView x:Name="tvGroups" Grid.Row="0">
        <sdk:TreeView.ItemTemplate>
            <sdk:HierarchicalDataTemplate ItemsSource="{Binding SubItems}">
                <TextBlock Text="{Binding ItemName}" Tag="{Binding ItemID}" MouseLeftButtonUp="TextBlock_MouseLeftButtonUp" />
            </sdk:HierarchicalDataTemplate>
        </sdk:TreeView.ItemTemplate>
    </sdk:TreeView>

    <TextBlock x:Name="txbParentToChild" Grid.Row="1"/>
</Grid>

背后的代码 -

namespace SilverlightApplication1
{
public class Group : INotifyPropertyChanged
{
    private String _strItemName;
    private Int32 _itemId;
    private ObservableCollection<Group> _subItems;

    public String ItemName
    {
        get { return _strItemName; }
        set { _strItemName = value; NotifyChange("ItemName"); }
    }

    public Int32 ItemID
    {
        get { return _itemId; }
        set { _itemId = value; NotifyChange("ItemID"); }
    }

    public ObservableCollection<Group> SubItems
    {
        get { return _subItems; }
        set { _subItems = value; NotifyChange("SubItems"); }
    }

    /// <summary>
    /// Called whenever any of the Group property is changed.
    /// </summary>
    /// <param name="PropertyName">Name of the property that has changed.</param>
    private void NotifyChange(String PropertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

public partial class MainPage : UserControl
{
    private ObservableCollection<Group> _lstItems;
    private Int32 _selectedItemId;

    public MainPage()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        _lstItems = new ObservableCollection<Group>();

        ObservableCollection<Group> childA = new ObservableCollection<Group>();
        childA.Add(new Group { ItemID = 1, ItemName = "ChildA", SubItems = null });

        ObservableCollection<Group> parent = new ObservableCollection<Group>();
        parent.Add(new Group { ItemID = 2, ItemName = "Child1", SubItems = null });
        parent.Add(new Group { ItemID = 3, ItemName = "Child2", SubItems = childA });
        parent.Add(new Group { ItemID = 4, ItemName = "Child3", SubItems = null });

        _lstItems.Add(new Group { ItemID = 5, ItemName = "Parent", SubItems = parent });

        tvGroups.ItemsSource = _lstItems;
    }

    private void TextBlock_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        TextBlock txbSource = sender as TextBlock;
        String strItems = String.Empty;
        if (txbSource != null)
        {
            _selectedItemId = -1;
            Int32.TryParse(txbSource.Tag.ToString(), out _selectedItemId);
            List<String> lstParent = new List<String>();
            if (_selectedItemId != -1)
            {
                lstParent = FindItem(_lstItems);
            }
            lstParent.Reverse();
            foreach(String strItem in lstParent)
            {
                strItems += strItem + " -> ";
            }
            strItems = strItems.Remove(strItems.Length - 4);
        }

        txbParentToChild.Text = strItems;
    }

    private List<String> FindItem(ObservableCollection<Group> lstCurrentGroup)
    {
        List<String> lstParent = new List<String>();
        foreach(Group grp in lstCurrentGroup)
        {
            if (grp.ItemID == _selectedItemId)
            {
                lstParent.Add(grp.ItemName);
                return lstParent;
            }
            else if (grp.SubItems != null)
            {
                lstParent = FindItem(grp.SubItems);
                if (lstParent.Count > 0)
                    lstParent.Add(grp.ItemName);
            }
        }
        return lstParent;
    }
}
}

每当用户单击树的节点时,上面的代码都会在 TextBlock 中显示父节点到叶节点的链接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    相关资源
    最近更新 更多