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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Получение доступа к элементу шаблона из кода 
:(
    Опции темы
ArtemCh
Дата 20.3.2010, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Всем доброго времени суток.
Недавно начал осваивать WPF и возникла следующая проблема с шаблонами.

У меня есть шаблон элемента управления для ListBoxItem-а (Хочу сделать редактируемый ListBox):

Код

       <Style x:Key="TextBoxListStyle" TargetType="{x:Type ListBox}">
            <Setter Property="ItemContainerStyle">
                <Setter.Value>
                    <Style TargetType="{x:Type ListBoxItem}">
                        <Setter Property="Margin" Value="2"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                    <TextBox Name="PART_TextBox" BorderThickness="0" 
                                             Text="{Binding Path=Content, Mode=OneWay, Converter={StaticResource RecordNameGetter},
                                                    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"/>
                                    <ControlTemplate.Triggers>
                                        <Trigger SourceName="PART_TextBox" Property="IsFocused" Value="True">
                                            <Setter Property="IsSelected" Value="True"/>
                                            <Setter TargetName="PART_TextBox" Property="BorderThickness" Value="1"/>
                                        </Trigger>
                                        <Trigger SourceName="PART_TextBox" Property="IsFocused" Value="False">
                                            <Setter Property="IsSelected" Value="False"/>
                                            <Setter TargetName="PART_TextBox" Property="BorderThickness" Value="0"/>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </Setter.Value>
            </Setter>
        </Style>
...
        <ListBox Name="lstSomeList" Style="{StaticResource TextBoxListStyle}"
                         SelectionChanged="OnSelectionChangeSomeList"/>


Трудность возникает в следующем: как мне из кода OnSelectionChangeSomeList добраться до свойства Text в определённом в шаблоне TextBox-е?
PM MAIL   Вверх
SergeyLoginov
Дата 24.3.2010, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 28.9.2009
Где: Иваново

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



Может попробовать получить экземпляр выделенного ListBoxItem'а (item) и найти TextBox с помощью вызова item.Template.FindName("PART_TextBox", item).
Это так... навскидку, сам не проверял. Можно еще порыть в сторону LogicalTreeHelper и VisualTreeHelper
PM MAIL   Вверх
ArtemCh
Дата 24.3.2010, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо.
То что вы предложили пробовал. Пытался даже в отладчике по веткам до TextBox-а добравться, но не получилось...
его просто нет в логическом дереве, хотя может не так искал.

Вообще я вопрос в более общем виде поставил, мне нужно было просто обновлять источник в привязке при потере фокуса у элемента списка. Так как в шаблоне приходится делать одностороннюю (он не видит если я явно свойство класса укажу). В итоге написал обработчик события и в шаблоне привязал к TextBox-у.

Шаблон:

Код

<TextBox Name="PART_TextBox" BorderThickness="0" 
         Text="{Binding Path=Content, Mode=OneWay, 
                Converter={StaticResource RecordNameGetter},
                RelativeSource={RelativeSource TemplatedParent}}"
         LostKeyboardFocus="OnLTBLostKeybordFocus"/>


Обработчик:

Код

private void OnLTBLostKeybordFocus(object sender, KeyboardFocusChangedEventArgs args)
{
    TextBox tb_sender = (TextBox)sender;
    if (typeof(SomeClass1) == tb_sender.DataContext.GetType())
    {
        SomeClass1 ob1 = (SomeClass1)tb_sender.DataContext;
        ob1.Name = tb_sender.Text;
    }
    else if (typeof(SomeClass2) == tb_sender.DataContext.GetType())
    {
        SomeClass2 ob2 = (SomeClass2)tb_sender.DataContext;
        ob2.Name = tb_sender.Text;
    }
}


Это работает, но мне всё же не нравится тем, что если я буду применять шаблон со списком объектов типа SomeClass3, надо дописывать обработчик. Хотелось бы всё таки найти ответ на изначально заданный вопрос. Хотя бы просто узнать в каких случаях возможно добраться из кода до элемента шаблона а в каких нет.
PM MAIL   Вверх
SergeyLoginov
Дата 25.3.2010, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 28.9.2009
Где: Иваново

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



Цитата(ArtemCh @ 24.3.2010,  22:32)
Спасибо.
То что вы предложили пробовал. Пытался даже в отладчике по веткам до TextBox-а добравться, но не получилось...
его просто нет в логическом дереве, хотя может не так искал.

Вообще я вопрос в более общем виде поставил, мне нужно было просто обновлять источник в привязке при потере фокуса у элемента списка. Так как в шаблоне приходится делать одностороннюю (он не видит если я явно свойство класса укажу). 


Не совсем понял пояснение, почему нельзя использовать двустороннюю привязку и указать UpdateSourceTrigger=LostFocus. Не ясно из контекста кто там кого не видит smile

Насчет поиска дочернего элемента. Я думаю, все же Вы просто не там (не так) ищете. Если TextBox есть в визуальном дереве ListBoxItem'а (а он судя по шаблону там присутствует), то его можно найти в коде.
Попробуйте, к примеру, использовать следующий код:

Код

        private T FindVisualChild<T>(DependencyObject element) where T : DependencyObject
        {
            int childrenCount = VisualTreeHelper.GetChildrenCount(element);
            if (childrenCount > 0)
            {                
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(element, i);
                    if (typeof(T).IsAssignableFrom(child.GetType()))
                    {
                        return (T)child;
                    }
                    else
                    {
                        T candidate = FindVisualChild<T>(child);
                        if (candidate != null)
                            return candidate;
                    }
                }
            }
            return null;
        }

       private void OnSelectionChangeSomeList(object sender, SelectionChangedEventArgs e)
        {
            //...
            //определили выделенный ListBoxItem именованный  selectedItem
            TextBox textBox = FindVisualChild<TextBox>(selectedItem);
        }

Опять же не отлаживал, данный код - небольшая непроверенная модификация ранее мной написанного. Под Ваши нужды, наверное, имеет смысл его изменить (например, ввести проверку имени, можно уйти от обобщенности). Но это все детали, главное - принцип.
Но все же мне кажется, было бы логичней в конкретном случае использовать UpdateSourceTrigger.
И насчет "Хотя бы просто узнать в каких случаях возможно добраться из кода до элемента шаблона а в каких нет.". Мне кажется, что в данном случае "кто ищет, тот всегда найдет" ;)

Это сообщение отредактировал(а) SergeyLoginov - 25.3.2010, 17:52
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




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


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

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