xceedsoftware / wpftoolkit

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

ComboBox not readonly when PropertyGrid is readonly #1630

Open ShinyHobo opened 3 years ago

ShinyHobo commented 3 years ago

I have my propertygrid set to readonly; all of the controls are readonly except for the comboboxes for my enums, however. How do I prevent users from selecting other options in the comboboxes (and consequently updating the SelectedObject)?

ShinyHobo commented 3 years ago

I solved this by binding the PropertyGrid SelectedObjectChanged event, and then updating the ComboBoxItems to be disabled on expansion:

        private void PropertyGrid_SelectedObjectChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            var grid = sender as Xceed.Wpf.Toolkit.PropertyGrid.PropertyGrid;
            var properties = grid.Properties.OfType<Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem>();
            foreach(var prop in properties)
            {
                prop.Loaded += Prop_Loaded;
            }
        }

        private void Prop_Loaded(object sender, RoutedEventArgs e)
        {
            var source = e.OriginalSource as Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem;
            if (source.Editor is Xceed.Wpf.Toolkit.PropertyGrid.Editors.PropertyGridEditorComboBox)
            {
                var editor = source.Editor as Xceed.Wpf.Toolkit.PropertyGrid.Editors.PropertyGridEditorComboBox;
                editor.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
            }
        }

        private void ItemContainerGenerator_StatusChanged(object sender, System.EventArgs e)
        {
            var itemContainerGenerator = sender as ItemContainerGenerator;
            if(itemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
            {
                foreach (var item in itemContainerGenerator.Items)
                {
                    var container = itemContainerGenerator.ContainerFromItem(item) as ComboBoxItem;
                    container.IsEnabled = false;
                }
            }
        }
XceedBoucherS commented 3 years ago

Hi, Thank you for pointing this out. For a standard ComboBox, when we set the IsReadOnly property to true, only the editable part is affected (IsEditable = true) but the popup can still be popped and the value modified.

This will be fixed in v4.1, where the PropertyItem's editor of type ComboBox will have their IsEnabled property set to false when the PropertyGrid has its IsReadOnly property true.