Home > OS >  MVVM : Custom TreeViewItem doesn't show up in TreeView If I set the DefaultStyleKeyProperty
MVVM : Custom TreeViewItem doesn't show up in TreeView If I set the DefaultStyleKeyProperty

Time:10-29

I have created a custom TreeViewItem called TreeViewTestItem. In this TreeViewTestItem there are customs properties, with one that I use to show an Image in the header of the TreeViewTestItem :

class TreeViewTestItem : TreeViewItem, INotifyPropertyChanged
{
    public ImageSource _image;
    public ImageSource Image
    {
        get
        {
            return _image;
        }
        set
        {
            _image = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Image"));
        }
    }

    static TreeViewTestItem()
    {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeViewTestItem), new FrameworkPropertyMetadata(typeof(TreeViewTestItem)));
    }

    public TreeViewTestItem()
    {
            PreviewMouseDown  = TreeViewTestItem_PreviewMouseDown;
            _image = (ImageSource)new ImageSourceConverter().ConvertFrom(new Uri(@"pack://application:,,,/DEBUG;component/Resources/Icons/square.png"));
    }
}

Here is my Generic.xaml file inside the Themes folder :

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-DEBUG.Views.Controls">

    <Style TargetType="{x:Type local:TreeViewTestItem}" BasedOn="{StaticResource {x:Type TreeViewItem}}">
        <Setter Property="HeaderTemplate">
            <Setter.Value>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Margin="0,0,0,3">
                        <Image Source="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:TreeViewTestItem}}, Path=Image, Mode=TwoWay}" VerticalAlignment="Center" Width="30" Height="30" />
                        <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}, Path=Header}" VerticalAlignment="Center" Margin="5,0,0,0" FontSize="18" />
                    </StackPanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

Here is my view where the TreeView should show :

<Window x:Class="DEBUG.Views.TestView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:src="clr-namespace:DEBUG.Views.Controls"
        xmlns:local="clr-namespace:DEBUG.Views"
        mc:Ignorable="d">
[...]
<TreeView ItemsSource="{Binding TreeViewTests}">
            </TreeView>
</Window>

And here is how I fill my TreeViewTests property :

class TestViewModel : MVVMHelper
    {
        public ObservableCollection<TreeViewTestItem> TreeViewTests { get; set; }
        [...]
        public TestViewModel(List<Test> testList)
        {
            TreeViewTests = new ObservableCollection<TreeViewTestItem>();
        }
        private void AddTestNode(TreeViewTestItem treeItem, List<Test> testList)
        {
            foreach (Test test in testList)
                {
                    TreeViewTestItem tvi = new TreeViewTestItem();
                    tvi.Test = test;
                    tvi.Header = test.LibelleEn;

                    if (treeItem == null)
                    {
                        TreeViewTests.Add(tvi);
                    }
                    else
                    {
                        treeItem.Items.Add(tvi);
                    }
                    AddTestNode(tvi, test.ListeTest);
                }
        }
    }

The Test property is another object that doesn't matter at the moment.

And now my problem : If I remove the DefaultStyleKeyProperty.OverrideMetadata from the static constructor in my TreeViewTestItem, the items are shown in my TreeView in my TestView. If I use it, my TreeView is empty.

I tried to move my custom item in the Themes folder, but it didn't worked. I tried to set the Style directly in my TestView but it also didn't worked. The path to my image is correct.

There is no Exception thrown at all, and no exception can be see in the exit window.

Does anyone have an idea on how I can make my custom TreeViewItem shown in my TreeView ?

CodePudding user response:

The problem is the Generic.xaml file is not loaded/find by the project.

The reason of this is because this project was an old Winform project transformed into a XAML project, and a line was missing inside the AssemblyInfo.cs:

[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

With this line added, everything works correctly.

  • Related