dimanche 28 juin 2015

WPF TreeViewItem subclass does not display text/data template

I made a subclass of TreeViewItem so I could have some custom fields, I have also created a style for the subclass but it doesn't display the text or the border attributes properly.

Xaml for the user control

<UserControl x:Class="Project.ProfilesPanel"
             xmlns="http://ift.tt/o66D3f"
             xmlns:x="http://ift.tt/mPTqtT"
             xmlns:mc="http://ift.tt/pzd6Lm" 
             xmlns:d="http://ift.tt/pHvyf2"
             xmlns:controls="clr-namespace:Project"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.Resources>
            <!--The HierarchicalDataTemplate used by TreeViewItems
                in the second level of the TreeView.-->
            <HierarchicalDataTemplate x:Key="Level2Data" ItemsSource="{Binding Path=Items}">
                <Border>
                    <TextBlock Text="{Binding Path=Title}" VerticalAlignment="Center" />
                </Border>
            </HierarchicalDataTemplate>

            <!--The HierarchicalDataTemplate used by TreeViewItems
                in the first level of the TreeView.-->
            <HierarchicalDataTemplate x:Key="Level1Data"
                  ItemsSource="{Binding Path=Items}"
                  ItemTemplate="{StaticResource Level2Data}">
                <Border Height="20">
                    <TextBlock Text="{Binding Path=Title}" VerticalAlignment="Center" />
                </Border>
            </HierarchicalDataTemplate>

            <Style TargetType="controls:MenuItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
                <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                <Setter Property="Focusable" Value="True" />
                <Setter Property="IsExpanded" Value="True" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="controls:MenuItem">
                            <StackPanel>
                                <Grid x:Name="GridBd" Margin="1">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="*" />
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto" />
                                        <RowDefinition />
                                    </Grid.RowDefinitions>
                                    <Border x:Name="TrueBd" Grid.Row="0" Grid.ColumnSpan="2">
                                        <ContentPresenter x:Name="SomeHeader"
                                                ContentTemplate="{TemplateBinding Property=HeaderTemplate}" />
                                    </Border>
                                    <ToggleButton IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
                                          ClickMode="Press" Name="Expander">
                                        <ToggleButton.Style>
                                            <Style TargetType="ToggleButton">
                                                <Setter Property="UIElement.Focusable" Value="false" />
                                                <Setter Property="FrameworkElement.Width" Value="16" />
                                                <Setter Property="FrameworkElement.Height" Value="16" />
                                                <Setter Property="Control.Template">
                                                    <Setter.Value>
                                                        <ControlTemplate TargetType="ToggleButton">
                                                            <Border Padding="5,5,5,5" Background="#00FFFFFF"
                                                                Width="16"
                                                                Height="16">
                                                                <Path Fill="#00FFFFFF"
                                                                    Stroke="Black"
                                                                    Name="ExpandPath">
                                                                    <Path.Data>
                                                                        <PathGeometry Figures="M0,0L0,6L6,0z" />
                                                                    </Path.Data>
                                                                    <Path.RenderTransform>
                                                                        <RotateTransform Angle="135"
                                                                        CenterX="3"
                                                                        CenterY="3" />
                                                                    </Path.RenderTransform>
                                                                </Path>
                                                            </Border>
                                                            <ControlTemplate.Triggers>
                                                                <Trigger Property="UIElement.IsMouseOver" Value="True">
                                                                    <Setter TargetName="ExpandPath"
                                                                        Property="Shape.Stroke"
                                                                        Value="#FF1BBBFA" />
                                                                    <Setter TargetName="ExpandPath"
                                                                        Property="Shape.Fill"
                                                                        Value="#00FFFFFF" />
                                                                </Trigger>
                                                                <Trigger Property="ToggleButton.IsChecked" Value="True">
                                                                    <Setter TargetName="ExpandPath" Property="UIElement.RenderTransform">
                                                                        <Setter.Value>
                                                                            <RotateTransform Angle="180"
                                                                                 CenterX="3"
                                                                                 CenterY="3" />
                                                                        </Setter.Value>
                                                                    </Setter>
                                                                    <Setter TargetName="ExpandPath"
                                                                        Property="Shape.Fill"
                                                                        Value="Black" />
                                                                    <Setter TargetName="ExpandPath"
                                                                        Property="Shape.Stroke"
                                                                        Value="Black" />
                                                                </Trigger>
                                                            </ControlTemplate.Triggers>
                                                        </ControlTemplate>
                                                    </Setter.Value>
                                                </Setter>
                                            </Style>
                                        </ToggleButton.Style>
                                    </ToggleButton>
                                    <Border x:Name="Bd"
                                        HorizontalAlignment="Stretch"
                                        BorderThickness="{TemplateBinding Border.BorderThickness}"
                                        BorderBrush="{TemplateBinding Border.BorderBrush}"
                                        Padding="{TemplateBinding Control.Padding}"
                                        Background="{TemplateBinding Panel.Background}"
                                        SnapsToDevicePixels="True"
                                        Grid.Column="1">
                                        <ContentPresenter x:Name="PART_Header"
                                            Content="{TemplateBinding HeaderedContentControl.Header}"
                                            ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
                                            ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}"
                                            ContentTemplateSelector="{TemplateBinding HeaderedItemsControl.HeaderTemplateSelector}"
                                            ContentSource="Header"
                                            HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                                            SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                                    </Border>
                                    <ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Row="1" />
                                </Grid>
                            </StackPanel>
                            <ControlTemplate.Triggers>
                                <Trigger Property="TreeViewItem.IsExpanded" Value="False">
                                    <Setter TargetName="ItemsHost" Property="UIElement.Visibility" Value="Collapsed" />
                                </Trigger>
                                <Trigger Property="ItemsControl.HasItems" Value="False">
                                    <Setter TargetName="TrueBd" Property="Background" Value="#FAFAFAFA"/>
                                    <Setter TargetName="Expander" Property="UIElement.Visibility" Value="Hidden" />
                                </Trigger>
                                <Trigger Property="ItemsControl.HasItems" Value="True">
                                    <Setter TargetName="TrueBd" Property="Background" Value="LightSteelBlue"/>
                                </Trigger>
                                <Trigger Property="TreeViewItem.IsSelected" Value="True">
                                    <Setter TargetName="TrueBd"
                                        Property="Background"
                                        Value="LightSkyBlue" />
                                    <Setter Property="TextElement.Foreground"
                                        Value="White" />
                                </Trigger>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition SourceName="PART_Header" Property="IsMouseOver" Value="True"/>
                                        <Condition Property="TreeViewItem.IsSelected" Value="False" />
                                    </MultiTrigger.Conditions>                 
                                        <Setter TargetName="TrueBd"
                                            Property="Background"
                                            Value="SteelBlue" />
                                        <Setter Property="TextElement.Foreground"
                                            Value="White" />
                                </MultiTrigger>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="TreeViewItem.IsSelected" Value="True" />
                                        <Condition Property="Selector.IsSelectionActive" Value="False" />
                                    </MultiTrigger.Conditions>
                                    <Setter TargetName="TrueBd"
                                        Property="Background"
                                        Value="LightSkyBlue" />
                                    <Setter Property="TextElement.Foreground"
                                        Value="White" />
                                </MultiTrigger>
                                <Trigger Property="UIElement.IsEnabled" Value="False">
                                    <Setter Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

        </Grid.Resources>

        <TreeView Name="trvMenu" ItemsSource="{Binding Items}" HorizontalAlignment="Stretch"
            ItemTemplate="{StaticResource Level1Data}"
            MouseRightButtonDown="TV_MouseRightButtonUp" />
    </Grid>
</UserControl>

And the Xaml.cs looks like

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace Project
{
    /// <summary>
    /// Interaction logic for ProfilesPanel.xaml
    /// </summary>
    public partial class ProfilesPanel : UserControl
    {
        public ProfilesPanel()
        {
            InitializeComponent();
            MenuItem sears = new MenuItem() { Title = "Sears", Type = "Org" };
            sears.Items.Add(new MenuItem() { Title = "Child item #1", Type = "Profile" });
            sears.Items.Add(new MenuItem() { Title = "Child item #2", Type = "Profile" });
            trvMenu.Items.Add(sears);

            MenuItem macys = new MenuItem() { Title = "Macys", Type = "Org" };
            macys.Items.Add(new MenuItem() { Title = "Child item #1", Type = "Profile" });
            macys.Items.Add(new MenuItem() { Title = "Child item #2", Type = "Profile" });
            macys.Items.Add(new MenuItem() { Title = "Child item #3", Type = "Profile" });
            macys.Items.Add(new MenuItem() { Title = "Child item #4", Type = "Profile" });
            trvMenu.Items.Add(macys);
        }

        private void TV_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            trvMenu.Items.Remove(trvMenu.SelectedItem);
        }
    }

    public partial class MenuItem : TreeViewItem
    {
        public string Title { get; set; }
        public string Type { get; set; }
    }
}

The style was developed with a two level Tree in mind where the first level has a larger border with a background color. The children have a different background color. The tree is displayed with the style and background colors but the border size and text defined in the HierarchicalDataTemplates do not show up correctly. The text field is blank.

My suspicion is that I am missing something in the style I am using to display the MenuItem, but I am fairly new to WPF so I don't know what I am missing.

Aucun commentaire:

Enregistrer un commentaire