0

我想用可编辑的节点制作 TreeView。正如我认为的那样,我在谷歌上搜索了这篇很好的文章:

http://www.codeproject.com/Articles/31592/Editable-TextBlock-in-WPF-for-In-place-Editing

但我有一个问题。我的 TreeView 动态地形成,而不是像北极那样静态地形成。像那样

    <TreeView Name="_packageTreeView" Margin="5" ItemsSource="{Binding PackageExtendedList}">
         <TreeView.InputBindings>
             <KeyBinding Key="C" Command="{Binding *TestCommand*}" CommandParameter="{Binding}" />
         </TreeView.InputBindings>
         <i:Interaction.Triggers>
             <i:EventTrigger EventName="SelectedItemChanged">
                 <i:InvokeCommandAction Command="{Binding PackageTreeItemChangeCommand}" CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}"/>
             </i:EventTrigger>
         </i:Interaction.Triggers>
         <TreeView.ItemContainerStyle>
             <Style TargetType="{x:Type TreeViewItem}">
                 <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
             </Style>
         </TreeView.ItemContainerStyle>
         <TreeView.ItemTemplate>
             <HierarchicalDataTemplate DataType="{x:Type MasterBuisnessLogic:RootDocPackage}" ItemsSource="{Binding Path=Childs}">
                 <Grid>
                     <Grid.ColumnDefinitions>
                         <ColumnDefinition>
                         </ColumnDefinition>
                         <ColumnDefinition>
                         </ColumnDefinition>
                     </Grid.ColumnDefinitions>
                    <Image Source="/Resources/DocGroup.png"></Image>
                    <Etb:EditableTextBlock Margin="5,0,0,0" Grid.Column="1" Text="{Binding Path=Name}"></Etb:EditableTextBlock>
                 </Grid> 
             </HierarchicalDataTemplate>
         </TreeView.ItemTemplate>
     </TreeView>

PackageExtendedList - DocPackageExtended 列表。

那么,第一个问题 - 如何在 TestCommand 中获取 TreeViewItem 实例?不是实例DocPackageExtended类!我想像文章中那样获取实例选择的TreeViewItem

第二个问题 - 在我获得实例TreeViewItem后,如何从 TreeView 项的 DataTemplate 中获得EditableTextBlock 。

添加答案

我已经试过了。因为在 MVVM ViewModel 中不能有任何链接到像 TreeView 这样的 View 对象,我在代码隐藏中制作处理程序,就像那样

private void TreeViewItemSelected(object sender, RoutedEventArgs e)
{
    // Already have TreeViewItem instance without of ItemContainerGenerator help
    var tvi = e.OriginalSource as TreeViewItem;

    if (tvi == null)
        return;

    var etb = VisualTreeLib.VisualTreeLib.GetVisualChild<EditableTextBlock>(tvi);
    if (etb == null)
        return;

    // Do what I want
    etb.IsEditable = true;
}

不幸的是,这没有任何影响:(

我也尝试过这种方法,但也失败了。

在 DocPackageExtended 类型中我定义了属性

public bool IsEditable
{
    get { return _isEditable; }
    set
    {
        _isEditable = value;
        OnPropertyChanged(new PropertyChangedEventArgs("IsEditable"));
    }
}

比 XAML 中的变化:

<Etb:EditableTextBlock Margin="5,0,0,0" Grid.Column="1" Text="{Binding Path=Name}" *IsEditable="{Binding Path=IsEditable}"*/>

在 ViewModel 中

private void TestCommandMethod(object obj)
{
    var dpe = obj as DocPackageExtended;
    if (dpe == null)
       return;
    dpe.IsEditable = true;
}

也不起作用:(有什么想法吗?

4

2 回答 2

0

第一个问题:由于似乎可以选择多个条目,因此需要在TestCommand的执行方法中过滤所有选择的条目:

IEnumerable<DocPackageExtended> selectedEntries = PackageExtendedList.Where(d => d.IsSelected);

如果禁用了多选,您可以将 TreeView 的选定项绑定到 VM 中的属性,并在 TestCommand 的方法中访问此属性。

第二个问题:你通过var container = YourTreeViewInstance.ItemContainerGenerator.ContainerFromItem(dataInstance);. 现在你必须在VisualTreeHelper的帮助下遍历这个容器,直到它找到一个 type 的控件EditableTextBlock。但我不会在 ViewModel 中执行此操作,而是在辅助类中或在附加属性的帮助下执行此操作。

编辑:您将类属性中实例的 IsEditable 属性绑定ChildsDocPackageExtendedEditableTextBox,但在您中,TestCommandMethod您正在IsEditable直接操作 DocPackageExtended 实例的属性。您可以执行以下操作:

private void TestCommandMethod(object obj)
{
    var dpe = obj as DocPackageExtended;
    if (dpe == null)
       return;
    dpe.IsEditable = true;
    foreach (RootDocPackage rdp in dpe.Childs)
    {
        rdp.IsEditable = true;
    }
}
于 2013-09-23T09:01:50.597 回答
0

这可能会帮助你。

private void Button_Click(object sender, RoutedEventArgs e)
    {
        TreeViewItem treeViewItemFound = GetItem(MyTreeview, MyTreeview.SelectedItem);
        ContentPresenter header = treeViewItemFound.Template.FindName("PART_Header", treeViewItemFound) as ContentPresenter;
        if (header != null)
        {
            TextBox myTextBox = (TextBox)header.ContentTemplate.FindName("MyTextBox", header);
        }
    }

    public TreeViewItem GetItem(ItemsControl container, object itemToSelect)
    {
        foreach (object item in container.Items)
        {
            if (item == itemToSelect)
            {
                return (TreeViewItem)container.ItemContainerGenerator.ContainerFromItem(item);
            }
            else
            {
                ItemsControl itemContainer = (ItemsControl)container.ItemContainerGenerator.ContainerFromItem(item);
                if (itemContainer.Items.Count > 0)
                {
                    TreeViewItem treeViewItemFound = GetItem(itemContainer, itemToSelect);
                    if (treeViewItemFound != null)
                        return treeViewItemFound;
                }
            }
        }

        return null;
    }
于 2013-09-23T11:37:47.457 回答