我希望使用可编辑节点制作TreeView。正如我想的那样,我用谷歌搜索了这篇文章:
http://www.codeproject.com/Articles/31592/Editable-TextBlock-in-WPF-for-In-place-Editing
但我有问题。我的TreeView形成了dinamically,而不是像arcticle那样静态。像那样
<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;
}
也不起作用:( 有什么想法吗?
答案 0 :(得分:0)
第一个问题:由于您似乎可以选择多个条目,因此需要在TestCommand执行的方法中过滤所有选定的条目:
IEnumerable<DocPackageExtended> selectedEntries = PackageExtendedList.Where(d => d.IsSelected);
如果禁用了多个选择,您可以将TreeView的选定项绑定到VM中的属性,并在TestCommand的方法中访问此属性。
第二个问题:您通过var container = YourTreeViewInstance.ItemContainerGenerator.ContainerFromItem(dataInstance);
获取了dataitem的容器。现在,您必须在VisualTreeHelper的帮助下浏览此容器,直到找到类型EditableTextBlock
的控件。但我不会在ViewModel中这样做,而是在辅助类中或在附加属性的帮助下。
编辑:您正在将Childs
类的DocPackageExtended
属性中的实例的IsEditable属性绑定到EditableTextBox,但在TestCommandMethod
中,您正在操纵IsEditable
1}} 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;
}
}
答案 1 :(得分: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;
}