Модераторы: gambit, Kefir, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Редактируемые Items в TreeView 
V
    Опции темы
Тигер
Дата 21.7.2013, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 4.4.2010

Репутация: нет
Всего: нет



Вобщем, смысл в том что я хочу сделать корневые Items в TreeView редактируемымми.
Для этого планирую заменять их на TextBox
XAML
Код

   <TreeView Height="182" Name="infoBox_treeview" Margin="0,2,0,182" BorderBrush="#FFA5A5A5" BorderThickness="2">
            <TreeViewItem Header="t1"></TreeViewItem>
            <TreeViewItem Header="t2">
                <TreeViewItem Header="t21"></TreeViewItem>
                <TreeViewItem Header="t22"></TreeViewItem>
            </TreeViewItem>
            <TreeViewItem Header="t3"></TreeViewItem>
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <EventSetter Event="MouseDoubleClick" Handler="infobox_item_edit"></EventSetter>
                </Style>
            </TreeView.ItemContainerStyle>
            <TreeView.ContextMenu>
                <ContextMenu Name="infoBox_treeview_menu">
                    <MenuItem Header="Добавить ссылку" Name="infobox_menu_addlink" Click="infobox_menu_addlink_Click"></MenuItem>
                    <MenuItem Header="Удалить ссылку" Name="infobox_menu_dellink"></MenuItem>
                </ContextMenu>
            </TreeView.ContextMenu>
        </TreeView>


в C#:
Код

private void infobox_item_edit(object sender, RoutedEventArgs e)
{
    var selItem=(TreeViewItem)this.infoBox_treeview.SelectedItem;
    selItem.Header = new TextBox() { Text = selItem.Header.ToString() };
}


Проблема в том что событие DoubleClick вешается на все Items и не только на корневые.
И так же возникают сомнения в оптимальности подхода к решению задачи.

Попутно вопрос: Почему вот этот код работает некорректно и отображает Ноль
Код

this.MainTree.Items.Add(
    ( new TreeViewItem { Header = "t0" } )
    .Items.Add(
        new TreeViewItem { Header = "t01" }
    )
);


Спасибо!

Это сообщение отредактировал(а) Тигер - 21.7.2013, 10:10
PM MAIL   Вверх
dzaraev
Дата 22.7.2013, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 149
Регистрация: 12.1.2013

Репутация: нет
Всего: 1



Сразу хочу заметить - что у вас ошибка в infobox_item_edit: вы не проверяете infoBox_treeview.SelectedItem на null. Поэтому, если дважды кликнуть не по хедеру, а по стрелочке слева, и у дерева не будет выбранного элемента, вы получите NullReferenceException.
Цитата(Тигер @  21.7.2013,  10:08 Найти цитируемый пост)
Проблема в том что событие DoubleClick вешается на все Items и не только на корневые.

Во-первых, сам стиль общий - т.е. задан для всех элементов дерева.
Во-вторых, когда выкликаете по дочернему элементу, в качестве инициатора события выступает корневой родительский элемент, потому что он размещает в себе дочерние, и по факту - вы кликаете по нему. 
Поскольку sender - всегда корневой элемент, то самое простое решение вашей задачи, это проверять на тождественность отправителя и выделенный элемент:
Код

        private void infobox_item_edit(object sender, MouseButtonEventArgs e)
        {
            var selItem = (TreeViewItem)this.infoBox_treeview.SelectedItem;
            if (!ReferenceEquals(sender, selItem))
            {
                return;
            }
            selItem.Header = new TextBox() { Text = selItem.Header.ToString() };
        }


Далее,
Цитата(Тигер @  21.7.2013,  10:08 Найти цитируемый пост)
И так же возникают сомнения в оптимальности подхода к решению задачи.

Оптимальность конечно не очень. Более удачный подход - использовать DataTemplate для хедера. И устанавливать его на свойство TreeViewItem.HeaderTemplate по нужной логике (либо сразу - статически). Вот пример такого подхода: http://dedjo.blogspot.ru/2007/05/create-ed...item-using.html
не совсем ваша задача, но думаю вы разберётесь. Если всё же возникнут  вопросы - спрашивайте.

Цитата(Тигер @  21.7.2013,  10:08 Найти цитируемый пост)
Попутно вопрос: Почему вот этот код работает некорректно и отображает Ноль

this.MainTree.Items.Add(
    ( new TreeViewItem { Header = "t0" } )
    .Items.Add(
        new TreeViewItem { Header = "t01" }
    )
);


Очень перегруженная операция, поэтому вы сами запутались в ней.
Давайте просто напишем тоже самое, но не жалея строчек кода:
Код

            TreeViewItem newItem = new TreeViewItem {Header = "t0"};
            TreeViewItem subItem = new TreeViewItem {Header = "t01"};
            int addedIndex = newItem.Items.Add(subItem);
            this.MainTree.Items.Add(addedIndex);

Теперь стало очевидно, что вы просто пихаете в корневые элементы дерева значение, которое возвращает метод Add, а он возвращает вот такой int:
Цитата

Returns:
The zero-based index at which the object is added or -1 if the item cannot be added.

Соответственно, при добавлении одного единственного под-элемента, Add добавил его по индексу 0. И этот ноль вы и засунули в дерево в качестве корневого элемента.
Ну и теперь правильный вариант:
Код

            TreeViewItem newItem = new TreeViewItem {Header = "t0"};
            TreeViewItem subItem = new TreeViewItem {Header = "t01"};
            newItem.Items.Add(subItem);
            this.MainTree.Items.Add(newItem);


Это сообщение отредактировал(а) dzaraev - 22.7.2013, 09:28
--------------------
Если вопрос решён - помечайте тему.  
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




[ Время генерации скрипта: 0.0474 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.