Во общем пытаюсь реализовать файловый експлорер, уже почти все сделал, но тут какая то непонятная ситуация у меня...
Когда я пытаюсь переместить ноду(то есть как бы файл перемещаю из одной папки в другую), вот таким вот кодом:
...
TreeViewItem node; // Node to move
TreeViewItem oldFolder = (TreeViewItem)node.Parent;
oldFolder.Items.Remove(node);
newFolder.Items.Add(node);
...
То итем теряет все байндинги и обработчики ивентов этого итема...
Вопрос: Как переместить TreeViewItem в TreeView так, что бы этот итем сохранил все свои свойства байндинги ивенты и все остальное, то есть как скопировать TreeViewItem в другой TreeViewItem?
UPDATE1: Ну может быть совсем уж все не теряет, но те на которые подписываюсь я - теряет... Вот как у меня все устроено: Стиль итема
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate x:Name="HeaderTemplateKey">
<StackPanel x:Name="PART_InnerPanel" Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Center"
Height="20">
<TextBlock x:Name="HeaderText" Text="{Binding}" Margin="7,1,0,0"
VerticalAlignment="Center" />
<TextBox x:Name="PART_EditableHeader" Text="{Binding Text, ElementName=HeaderText}"
Margin="2,2"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"
Visibility="{Binding IsEdit, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Controls:MyTreeViewItem}},
Converter={StaticResource boolToVisibilityConverter}, Mode=OneWay}">
</TextBox>
</StackPanel>
</DataTemplate>
</Setter.Value>
Потом в классе ноды я получаю PART_EditableHeader и подписываюсь на его ивенты, вот код этого всего:
public TextBox EditableHeader;
public void MyTreeViewItem_LayoutUpdated(object sender, EventArgs e)
{
ContentPresenter headerContentPreseter = this.Template.FindName("PART_Header", this) as ContentPresenter;
if (headerContentPreseter != null)
{
EditableHeader = this.HeaderTemplate.FindName("PART_EditableHeader", headerContentPreseter) as TextBox;
}
LayoutUpdated -= MyTreeViewItem_LayoutUpdated;
OnHeaderLoaded();
}
void OnHeaderLoaded()
{
if (EditableHeader != null)
{
KeyboardFocusChangedEventHandler preselect = delegate
{
// Do work...
};
EditableHeader.PreviewGotKeyboardFocus += preselect;
EditableHeader.GotKeyboardFocus += preselect;
EditableHeader.PreviewMouseDown += (s, e) =>
{
// Do work...
};
EditableHeader.LostFocus += delegate
{
// Do work...
};
EditableHeader.PreviewMouseDoubleClick += (s, e) =>
{
// Do work...
};
}
}
И все как бы работает нормально, до первого перемещения ноды, как только я перемещаю сразу перестают работать все обработчики описанные в методе OnHeaderLoaded(). Пока что по дебагу такое ощущение что мне нужно просто обновить еще раз EditableHeader, но почему-то когда пытаюсь обновить тем же способом то получаю ContentPresenter headerContentPreseter == null...
Короче я уже ничего не понимаю почему оно не работает... Помогите разобраться...
UPDATE2: Вот как биндится:
var tabItem = new TabItem();
TextBlock tb = new TextBlock();
Binding b = new Binding
{
Source = node,
Mode = BindingMode.OneWay,
Path = new PropertyPath(TreeViewNode.HeaderProperty)
};
tb.SetBinding(TextBlock.TextProperty, b);
b = new Binding
{
Source = node,
Mode = BindingMode.OneWay,
Path = new PropertyPath(TreeViewNode.PathProperty)
};
tabItem.SetBinding(TabItem.ToolTipTextProperty, b);
EditableHeader. (Вот немного почитать близко к теме.) – VladD Sep 14 '15 at 20:31OnApplyTemplateи там получаю исключениеthis.HeaderTemplate.FindName("PART_EditableHeader", header) threw an exception of type 'System.InvalidOperationException'... – SkyDancer Sep 22 '15 at 09:00LayoutUpdatedнаLoadedи вроде теперь получается так: Я удаляю ноду - вызываетсяUnloaded, потом я добавляю эту ноду в другую ноду и вызываетсяLoadedэтой ноды, и в этом ивенте я обновляю все элементы, и теперь работают все байндинги и все во обще вроде заработало как нужно, сейчас еще подебажу посмотрю может где то еще будет баг, но пока что выглядит как будто все нормльно работает. Почему не работало приOnApplyTemplateя так и не понял, в исключении ничего нету.. – SkyDancer Sep 22 '15 at 09:29Dependency property-Pathи к нему байндитсяTextBlock.TextPropertyв моей программе, но когда нода удаляется(теряет родителя) то этот байндинг слетает и больше не работает... Но когда я перемещаю как бы файлы вместе с папкой, то есть перемещаю ноду-родителя полностью, вместе с вложенными нодами, то тогда все работает нормально, и байндинги не слетают... – SkyDancer Sep 22 '15 at 11:14Source = node, видите? При переносе элемента, понятно,nodeсам по себе не изменится. Так что он всё ещё ссылается на старый, «мёртвый» экземплярnode. Вам нужно обновить его вручную, раз вы переставляете его таким образом. – VladD Sep 22 '15 at 14:17node. – VladD Sep 22 '15 at 15:59NodeUpdated, подписать на него метод моего объекта и уже там все поменять передав ноду аргументом этого ивента. – SkyDancer Sep 22 '15 at 16:39