none
как сотворить реестроподобный TreeView RRS feed

  • Вопрос

  • интересует сотворение по части наполнения, как в шарпе так и в xaml.

    собственно есть некий класс, который похож на Registry. есть такие методы, как getKeyNames и getSubKeyCount, но что бы ими воспользоваться, скажем для "папки" "Documents", нужно сначала вызвать метод .Open("Documents_parent"); где Doc_Parent - это родительский каталог. т.е. если открыть(Open) каталог, то можно получить имена его подкаталогов и количество подкаталогов в каждом из этих каталогов. [ Метода .getParent() не существует ]. Проблема в том, что я никак не могу написать обработчик раскрытия (+) каталога, который подходил бы для всех каталогов.

    если у кого-то есть советы или мысли или кто-то знает, как написать такой обработчик - милости прошу.

    18 июня 2012 г. 21:18

Ответы

  • Вам нужно будет перенастроить шаблон TreeViewItem и там задавать как будет визуализироваться выделение, но заранее определить в шаблоне отдельное место для картинки не получится, поэтому тут можно использовать кастыльный метод, то есть сделать margin у элемента имитирующего выделение "-21,0,0,0" (только все картинки должны иметь ширину в 19).

    Пример шаблона TreeViewItem смотрите здесь.


    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    • Изменено LXGDARKEditor 19 июня 2012 г. 10:56
    • Помечено в качестве ответа K_K 20 июня 2012 г. 11:00
    19 июня 2012 г. 10:51
    Отвечающий
  • Данная анимация применяется к свойству Background (а точнее к цвету внутри свойства) элемента по имени Bd. Фактически за 0 секунд (мгновенно) меняет фон элемента Bd на фон заданный в ресурсах. К слову вы можете вместо ссылки на ресурс задать, например, так - Value="Blue".

    По сути вам это часть XAML можно и не трогать, а просто как я и описывал выше сделать вложенную Border со сдвигом вправо и ее назвать Bd, тогда при выделении, анимация будет применяться к ней.

    Обратите внимание на этот участок XAML:

    <Border x:Name="Bd"
                      Grid.Column="1"
                      Background="{TemplateBinding Background}"
                      BorderBrush="{TemplateBinding BorderBrush}"
                      BorderThickness="{TemplateBinding BorderThickness}"
                      Padding="{TemplateBinding Padding}">
                <ContentPresenter x:Name="PART_Header"
                                  ContentSource="Header"
                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
              </Border>
    Вот с ним вам и нужно проделать эти действия. То есть вместо Border использовать Grid, а внутрь его класть ContentPresenter и Border с именем Bd и свойствами Panel.Zindex="-1", что бы он не перекрыл случайно ContentPresenter, а Margin="20,0,0,0"

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    • Изменено LXGDARKEditor 19 июня 2012 г. 15:09
    • Помечено в качестве ответа K_K 20 июня 2012 г. 11:00
    19 июня 2012 г. 15:08
    Отвечающий

Все ответы

  • Посмотрите вот этот топик. Должно помочь.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    19 июня 2012 г. 3:00
    Отвечающий
  • Добрый день.

    На форуме недавно спрашивали про показ странных иерархий в TreeView. Посмотрите здесь, может поможет. Если нет, то опишите вашу проблему поподробнее. А то что то не очень понятно, чего вы хотите получить на выходе.

    19 июня 2012 г. 6:01
    Отвечающий
  • Посмотрите вот этот топик. Должно помочь.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!


    Сохраняйте имена каталогов или полный путь в свойсвте Tag, как в топике, что привел LXGDARK. Это должно решить проблему. По сути вам нужно выполнять одни и теже действия, только для разных путей.

    Для связи [mail]

    19 июня 2012 г. 10:06
  • да, сохранение пути в Tag помогло. Спасибо.

    еще вопрос, уже по декоративной части - 

    в реестре Windows(к примеру) при выделении какого-нибудь каталога, выделяется только текст, а не иконка вместе с текстом. 

    я попробовал прилепить иконку к итему таким способом:

    <TreeViewItem.Header>
       <StackPanel Orientation="Horizontal">
         <Image Source="Images/img.png" Height="20" Width="19"></Image>
         <TextBlock Text="someItem" VerticalAlignment="Center" Margin="5,0,0,0"></TextBlock>
       </StackPanel>
    </TreeViewItem.Header>

    но при таком раскладе под выделение попадают и TextBlock и Image. есть способ организации этого дела, подобный тому, как это огранизованно  в  regedit?

    19 июня 2012 г. 10:44
  • Вам нужно будет перенастроить шаблон TreeViewItem и там задавать как будет визуализироваться выделение, но заранее определить в шаблоне отдельное место для картинки не получится, поэтому тут можно использовать кастыльный метод, то есть сделать margin у элемента имитирующего выделение "-21,0,0,0" (только все картинки должны иметь ширину в 19).

    Пример шаблона TreeViewItem смотрите здесь.


    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    • Изменено LXGDARKEditor 19 июня 2012 г. 10:56
    • Помечено в качестве ответа K_K 20 июня 2012 г. 11:00
    19 июня 2012 г. 10:51
    Отвечающий
  • про margin я понял, а вот про то, что касается перенастройки и "элемента имитирующего выделение" можно поподробнее?

    где этот элемент и где мне перенастроить шаблон? вы меня извините, но с шаблонами я не знаком совсем..

    19 июня 2012 г. 11:27
  • В ссылке что я вам дал в самом низу есть ссылка "Стилизация и использование шаблонов". Почитайте этот материал.

    По сути все элементы WPF построены из других элементов, а эффекты вроде выделения это манипуляции с частями шаблона. Вот предположим, что часть Header в TreeViewItem это Border внутрь которого передается содержимое заголовка. Когда делаем выделение Border  меняет фон и мы получаем эффект выделения. Если же мы заменим Border  на Grid внутри которого поместим элемент принимающий содержимое с заголовком и Border  который сдвинем на 21 (выше я ошибочно написал -21, это не правильно), тогда будет "выделятся" не весь заголовок а только часть.

    В общем читайте про стилизацию и использование шаблонов, изучайте пример шаблона и вам станет понятны мои слова.


    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    19 июня 2012 г. 11:35
    Отвечающий
  • как получается выделение и зачем сдвиг я хорошо понял. я не понял где конкретно в коде это место и как в XAML происходит переопределение шаблонов. т.е. куда этот километр кода надо подсунуть, что бы стало окей

    19 июня 2012 г. 11:49
  • Вот смотрите в описании класса ControlTemplate внизу есть пример переопределения шаблона кнопки. То же самое действует для TreeViewItem, только шаблон спицефичен для него.

    Я бы мог вам написать такой шаблон, но тогда вы сами это делать не скоро научитесь. Вот как я изучал шаблоны. Брал шаблон, вставлял его в свой XAML (как показано в ссылке "пример"), а потом начинал с ним "играть", изменяя части, меняя цвета и д.т. Так методом научного тыка я понял принцип построения шаблонов (конечно с попутным чтением полезных источников, вроде тех что я вам дал).


    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    19 июня 2012 г. 11:57
    Отвечающий
  • <VisualState x:Name="Selected">
      <Storyboard> 
      <ColorAnimationUsingKeyFrames Storyboard.TargetName="Bd" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
      <EasingColorKeyFrame KeyTime="0" Value="{StaticResource SelectedBackgroundColor}" />
      </ColorAnimationUsingKeyFrames>
     </Storyboard>
    </VisualState>
    ставит меня в тупик...
    19 июня 2012 г. 12:59
  • Данная анимация применяется к свойству Background (а точнее к цвету внутри свойства) элемента по имени Bd. Фактически за 0 секунд (мгновенно) меняет фон элемента Bd на фон заданный в ресурсах. К слову вы можете вместо ссылки на ресурс задать, например, так - Value="Blue".

    По сути вам это часть XAML можно и не трогать, а просто как я и описывал выше сделать вложенную Border со сдвигом вправо и ее назвать Bd, тогда при выделении, анимация будет применяться к ней.

    Обратите внимание на этот участок XAML:

    <Border x:Name="Bd"
                      Grid.Column="1"
                      Background="{TemplateBinding Background}"
                      BorderBrush="{TemplateBinding BorderBrush}"
                      BorderThickness="{TemplateBinding BorderThickness}"
                      Padding="{TemplateBinding Padding}">
                <ContentPresenter x:Name="PART_Header"
                                  ContentSource="Header"
                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
              </Border>
    Вот с ним вам и нужно проделать эти действия. То есть вместо Border использовать Grid, а внутрь его класть ContentPresenter и Border с именем Bd и свойствами Panel.Zindex="-1", что бы он не перекрыл случайно ContentPresenter, а Margin="20,0,0,0"

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    • Изменено LXGDARKEditor 19 июня 2012 г. 15:09
    • Помечено в качестве ответа K_K 20 июня 2012 г. 11:00
    19 июня 2012 г. 15:08
    Отвечающий
  • Спасибо, сделал.
    20 июня 2012 г. 11:00