XAML MVVM:如果设置DefaultStyleKeyProperty,则自定义树视图项不会显示在树视图中

vh0rcniy  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(159)

我已经创建了一个名为TreeViewTestItem的自定义TreeViewItem。在这个TreeViewTestItem中有一些自定义属性,其中一个我用来在TreeViewTestItem的标头中显示一个Image:

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"));
    }
}

下面是我在Themes文件夹中的Generic.xaml文件:

<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>

下面是TreeView应该显示的视图:

<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>

下面是我填充TreeViewTests属性的方法:

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);
                }
        }
    }

Test属性是另一个目前无关紧要的对象。
现在我的问题是:如果我从我的TreeViewTestItem的静态构造函数中移除DefaultStyleKeyProperty.OverrideMetadata,这些项将显示在我的TestView的TreeView中。如果我使用它,我的TreeView将为空。
我尝试在“主题”文件夹中移动自定义项目,但没有成功。我尝试直接在TestView中设置样式,但也没有成功。图像的路径是正确的。
根本没有抛出异常,并且在退出窗口中看不到异常。
有人知道如何让我的自定义TreeViewItem显示在我的TreeView中吗?

tkclm6bt

tkclm6bt1#

问题是项目未加载/查找Generic.xaml文件。
这是因为该项目是一个转换为XAML项目的旧Winform项目,并且AssemblyInfo.cs中缺少一行:

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

添加了这一行后,一切都正常工作。

相关问题