xceedsoftware / wpftoolkit

All the controls missing in WPF. Over 1 million downloads.
Other
3.9k stars 878 forks source link

PropertyGrid: OnPreparePropertyItem is not getting called #1670

Closed cdytoby closed 2 years ago

cdytoby commented 3 years ago

Code:

CS:

    public partial class PropertyGridWindow: Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public GameCatalogItem editItem { get; set; }

        public PropertyGridWindow()
        {
            editItem = new GameCatalogItem()
            {
                name = "NewGameName",
                platform = new[] { GamePlatform.Android, GamePlatform.PC }
            };
            Debug.WriteLine("PropertyGridWindow creating");

            InitializeComponent();
        }

        public void OnPreparePropertyItem(object sender, PropertyItemEventArgs e)
        {
            Debug.WriteLine("EditPropertyGridOnPreparePropertyItem called");
            editPropertyGrid.PropertyDefinitions.Add(new PropertyDefinition()
            {
                TargetProperties = new List<string>() { nameof(GameCatalogItem.name) },
                DisplayName = "name",
                IsBrowsable = true,
                Description = "des"
            });
            editPropertyGrid.PropertyDefinitions.Add(new PropertyDefinition() { TargetProperties = new List<string>() { nameof(GameCatalogItem.year) } });
        }

    }

XAML:

<Window x:Class="PersonalCollectionManager.WPFCore.PropertyGrid.PropertyGridWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:PersonalCollectionManager.WPFCore.PropertyGrid"
    xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
    mc:Ignorable="d"
    Title="PropertyGridWindow" Height="450" Width="800"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <!-- https://github.com/xceedsoftware/wpftoolkit/wiki/PropertyGrid -->
    <Grid>
        <xctk:PropertyGrid
            x:Name="editPropertyGrid"
            AutoGenerateProperties="False"
            ShowSortOptions="False"
            ShowSearchBox="False"
            ShowSummary="False"
            ShowPreview="False"
            ShowTitle="False"
            SelectedObject="{Binding editItem}"
            PreparePropertyItem="OnPreparePropertyItem">
            <!-- <xctk:PropertyGrid.PropertyDefinitions> -->
            <!--    <xctk:PropertyDefinition TargetProperties="name"/> -->
            <!-- </xctk:PropertyGrid.PropertyDefinitions> -->
        </xctk:PropertyGrid>
    </Grid>
</Window>

The issue: Debug.WriteLine("EditPropertyGridOnPreparePropertyItem called"); this line is not displayed in Debug console, and the properties are not displayed in this propertygrid control, it's empty.

The thing I want to achieve is, I want to add PropertyDefinitions dynamically in cs code, not in xaml, because there will be different types and I want to reuse the same property grid window. I found in documentation somewhere that I should use PreparePropertyItem event, but it seems it's not getting called. I can confirm that directly set propertydefinition in xaml works.

Also, is it because I'm using WPF with .NET 5?

XceedBoucherS commented 3 years ago

Hi,

You are setting AutoGenerateProperties to false...so no properties are displayed in the PropertyGrid. When setting this property to false, you must specify the properties you want to see with PropertyGrid.PropertyDefinitions.

The "OnPreparePropertyItem" will be called when a new property will be added to the PropertyGrid : when none are added, it won't be called.

Following your example, you could start with a PropertyGrid.AutoGenerateProperties at False and use a button click: private void Button_Click( object sender, RoutedEventArgs e ) { editPropertyGrid.PropertyDefinitions.Add( new PropertyDefinition() { TargetProperties = new List<string>() { nameof( GameCatalogItem.name ) }, DisplayName = "test", IsBrowsable = true, Description = "des" } ); editPropertyGrid.PropertyDefinitions.Add( new PropertyDefinition() { TargetProperties = new List<string>() { nameof( GameCatalogItem.year ) } } ); }

This will add 2 properties in the PropertyGrid.

cdytoby commented 2 years ago

I'm going to close this one. I solved it but I don't know what I did to solve it.