WPF / XAML TreeView не выделяет узлы после привязки - PullRequest
3 голосов
/ 24 августа 2010

Итак, у меня проблема с TreeView.Если я строю древовидное представление статически, каждый узел в дереве можно выбрать, поскольку, когда я щелкаю по нему, он подсвечивается синим цветом, указывая, что узел выбран.

<TreeView 
    Grid.Column="0"
    Grid.Row="2"
    MinHeight="100" 
    MinWidth="100"
    BorderBrush="White"
    DataContext="{Binding Projects, Source={x:Static SizingApp:Manager.Instance}}">
<TreeViewItem Header="Project 1" IsExpanded="True">
    <TreeViewItem Header="Step 1" IsExpanded="True">
        <TreeViewItem Header="Load 1" IsExpanded="True"></TreeViewItem>
        <TreeViewItem Header="Load 2" IsExpanded="True"></TreeViewItem>
    </TreeViewItem>
    <TreeViewItem Header="Step 2" IsExpanded="True">
        <TreeViewItem Header="Load 1" IsExpanded="True"></TreeViewItem>
        <TreeViewItem Header="Load 2" IsExpanded="True"></TreeViewItem>
    </TreeViewItem>
</TreeViewItem>

ОднакоЯ связываюсь с TreeView, чтобы заполнить его.Кроме того, я связываюсь с объектами, которые реализуют класс BindableObjectBase3 Эмиля Джонгериуса .Это замечательная реализация базового класса, которая позволяет моим объектам быть привязываемыми и реализовывать интерфейс INotifyPropertyChanged с заботой о ручном управлении DependencyProperty.

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

    public abstract class MyCustomClass : BindableObjectBase3
{
    private string m_strName;

    public virtual string Name
    {
        get
        {
            using (this.GetPropertyTracker(() => this.Name))
            {
                return m_strName;
            }
        }
        set
        {
            this.SetValue(ref this.m_strName, value, () => this.Name);
        }
    }
}

public class Project : MyCustomClass
{
    private List<Step> m_steps;

    public List<Step> Steps
    {
        get
        {
            using (this.GetPropertyTracker(() => this.Steps))
            {
                return m_steps;
            }
        }
        set
        {
            this.SetValue(ref this.m_steps, value, () => this.Steps);
        }
    }
}

public class Step : MyCustomClass
{
    private List<Load> m_loads;

    public List<Load> Loads
    {
        get
        {
            using (this.GetPropertyTracker(() => this.Loads))
            {
                return m_loads;
            }
        }
        set
        {
            this.SetValue(ref this.m_loads, value, () => this.Steps);
        }
    }
}

public class Load : MyCustomClass
{
}

И это базовый XAML, который я использую для реализации TreeView:

<TreeView 
    Grid.Column="0"
    Grid.Row="2"
    MinHeight="100" 
    MinWidth="100"
    BorderBrush="White"
    DataContext="{Binding Projects, Source={x:Static SizingApp:Manager.Instance}}">
    <TreeView.Resources>
        <HierarchicalDataTemplate x:Key="LoadTemplate">
            <TreeViewItem Header="{Binding Path=Name}">
            </TreeViewItem>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate x:Key="StepTemplate">
            <TreeViewItem Header="{Binding Path=Name}" IsExpanded="True"
                    ItemsSource="{Binding Path=Loads}"
                    ItemTemplate="{StaticResource LoadTemplate}">
            </TreeViewItem>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate x:Key="ProjectTemplate">
            <TreeViewItem Header="{Binding Path=Name}" IsExpanded="True"
                    ItemsSource="{Binding Path=Steps}"
                    ItemTemplate="{StaticResource StepTemplate}">
            </TreeViewItem>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
    <TreeViewItem 
            Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=projectTree_Header}"
            ItemsSource="{Binding}"
            IsExpanded="True"
            Focusable="True"
            ItemTemplate="{StaticResource ProjectTemplate}">
    </TreeViewItem>
</TreeView>

Теперь все это работает нормально, когда идет связывание.Я могу привязаться к ObservableCollection , и когда я добавляю / удаляю / манипулирую проектами, TreeView соответствующим образом обновляется.

Однако единственный узел в TreeView, который кажется доступным для выбора, - это первый узел (тот, который являетсястатика).Все остальные узлы, созданные с помощью динамического связывания, не указывают, что они выбраны в графическом интерфейсе.Я ожидаю, что они также будут выделены синим цветом при нажатии.Но вместо этого они ничего не делают.У кого-нибудь есть идеи почему?

Ответы [ 2 ]

4 голосов
/ 25 августа 2010

Вы не должны явно определять TreeViewItems в ваших ItemTemplates. Причина, по которой вы не можете выбрать ни один из элементов, заключается в том, что у них нет родительского TreeView для управления поведением выбора. Вам нужно позволить TreeView генерировать элементы управления TreeViewItem для вас и использовать шаблоны элементов только для определения пользовательского интерфейса для заголовков и привязок для их элементов. Вместо этого используйте что-то вроде этого:

<Window.Resources>
    <HierarchicalDataTemplate x:Key="LoadTemplate">
        <TextBlock Text="{Binding Path=Name}"/>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate x:Key="StepTemplate" ItemsSource="{Binding Loads}" ItemTemplate="{StaticResource LoadTemplate}">
        <TextBlock Text="{Binding Path=Name}"/>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate x:Key="ProjectTemplate" ItemsSource="{Binding Steps}" ItemTemplate="{StaticResource StepTemplate}">
        <TextBlock Text="{Binding Path=Name}"/>
    </HierarchicalDataTemplate>
</Window.Resources>

<TreeView MinHeight="100" MinWidth="100" BorderBrush="White"
          ItemsSource="{Binding Path=Projects}"
          ItemTemplate="{StaticResource ProjectTemplate}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="True" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>
1 голос
/ 06 декабря 2010

Мой TreeView работает так же, как описал оригинальный постер. Я могу выбрать все в своем элементе управления TreeView, но если я выберу дочерний узел, родительский узел - это то, что выделяет, хотя он связывает и щелкает дочерний узел. Я попытался структурировать свой код так, чтобы он напоминал предложение Джона Боуэна, и все же получил те же результаты. Вот мой код XAML:

   <Fluent:RibbonWindow.Resources>
        <HierarchicalDataTemplate x:Key="MyTreeViewStyle" ItemsSource="{Binding Contacts}">
            <!-- Display the Index by showing it's Index string -->
            <StackPanel Orientation="Horizontal">
                <Image x:Name="img" Width="16" Height="16" Stretch="Fill" Source="Images\closedfolder16.png" />
                <TextBlock Text="{Binding Index}" Margin="5,0" ToolTip="{Binding Index}"/>
            </StackPanel>
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image x:Name="img2" Width="16" Height="16" Stretch="Fill" Source="Images\closedfolder16.png" />
                        <TextBlock Text="{Binding Name}" Margin="5,0" ToolTip="{Binding Name}"/>
                    </StackPanel>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
</Fluent:RibbonWindow.Resources>

Затем я использую его здесь в своем TreeView Control:

                <Grid>
                    <TreeView Margin="2,2,2,2" x:Name="MyTreeView" ItemTemplate="{StaticResource MyTreeViewStyle}" ItemContainerStyle="{StaticResource AlwaysExpand}" ScrollViewer.CanContentScroll="True" BorderThickness="0" TreeViewItem.Selected="btnDisplayContact_Click" />                       
                </Grid>

В результате этого снимка экрана обратите внимание на то, как родительский узел D выделяется после щелчка по дочернему узлу вместо подсвеченного дочернего узла:

http://home.swbell.net/davis32/Snapshot.png

Невозможно публиковать изображения, поэтому просто скопируйте и вставьте ссылку на URL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...