Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add or remove DisplayAttribute programmatically in WPF

Tags:

c#

wpf

Im creating some items in my UI in the following way

Buttons.cs

[Browsable(true)]
[Display(Order = 1, Name = "Object1", GroupName = "Objects", ResourceType typeof(Resources.DisplayNames) , AutoGenerateField =false)]

public ButtonViewModel Button1{ get; set; }

[Browsable(true)]
[Display(Order = 2, Name = "Object2", GroupName = "Objects", ResourceType typeof(Resources.DisplayNames) , AutoGenerateField =false)]

public ButtonViewModel Button2{ get; set; }

//etc

What im trying to do is show or hide these UI elements based on some condition. I saw that if i set AutoGenerateField to true/false i get the desired result, is there some way to set that value true/false at runtime? (if its even possible)

Is there another way to do this alltogether? Like adding/removing the display attribute each time.

EDIT

PropertyGridView.xaml

<Grid>       
        <telerik:RadPropertyGrid telerik:StyleManager.Theme="Fluent"  
                                 x:Name="PropertyGrid"
                                 IsGrouped="True"
                                 Item="{Binding SelectedItem}"
                                 PropertySetMode="Union"
                                 RenderMode="Flat"                                                               
                                 SortAndGroupButtonsVisibility="Collapsed">           
        </telerik:RadPropertyGrid>
    </Grid>

PropertyGridViewModel.cs


    public class PropertyGridViewModel : Screen, IPropertyGridViewModel, IHandle<ItemSelectionMessage>
    {
        private IEventAggregator _eventAggregator;

        private IItem _item;

        public PropertyGridViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator;

        }

        protected override void OnActivate()
        {
            base.OnActivate();
            _eventAggregator.Subscribe(this);
        }

        protected override void OnDeactivate(bool close)
        {
            base.OnDeactivate(close);
            _eventAggregator.Unsubscribe(this);
        }

        public IItem SelectedItem
        {
            get
            {
                return _item;
            }
            set
            {
                _item = value;
                NotifyOfPropertyChange(() => SelectedItem);
            }
        }

        public void Handle(ItemSelectionMessage message)
        {
            SelectedItem = message.Item;
        }  

    }


And the item that gets passed is Buttons.cs above.

like image 830
Kyriakos Xatzisavvas Avatar asked Aug 05 '26 11:08

Kyriakos Xatzisavvas


1 Answers

You could create two classes that are implemented IItem interface for each visibility states and set appropriate one to RadPropertyGrid based on current visibility state. But it will work only for not huge amount of visibility states (you have to create separate class for each of them). Other way is setting dynamically Display attribute for each property with reflexion. But I advice you following the first approach with splitting classes.

            // additional methods for getting appropriate instance of your class  
            public static List<Type> GetInterfaceTypes<Interface>()
            {
                Type serachInterface = typeof(Interface);

                List<Type> findClasses = serachInterface.Assembly.GetTypes().Where
                            (
                                t => t.IsClass && !t.IsAbstract &&
                                serachInterface.IsAssignableFrom(t)
                            ).ToList();

                return findClasses;
            }
            public static List<Interface> GetInstances<Interface>(params object[] paramArray)
            {
                List<Interface> returnInstances = new List<Interface>();
                List<Type> foundTypes = GetInterfaceTypes<Interface>();

                foundTypes.ForEach(x =>
                {
                    returnInstances.Add((Interface)Activator.CreateInstance(x,args:paramArray));
                });
                return returnInstances;
            }
           // your handler from PropertyGridViewModel.cs
            public IItem SelectedItem { get; private set; }
            public  void Handle(ItemSelectionMessage message)
            {
                IItem item = GetInstances<IItem>(_eventAggregator).FirstOrDefault(x => x.Visibility == message.Visibility);
                SelectedItem = item;
            }

            public class ItemSelectionMessage
           {
             public VisibilityStates Visibility { set; get; }

           }

    // enum that  is describe you visibility states
        public enum VisibilityStates
        {
            Button1,
            Button2
        }
    // interface and classes that are implemented visibility interface
        public interface IItem
        {
            VisibilityStates Visibility { get; }
        }

        public class Button1StateClass : IItem
        {
             public VisibilityStates Visibility { get => VisibilityStates.Button1; }

              [Browsable(true)]
              [Display(Order = 1, Name = "Object1", GroupName = "Objects", ResourceType typeof(Resources.DisplayNames), AutoGenerateField = true)]

                public ButtonViewModel Button1 { get; set; }
 public Button1StateClass(IEventAggregator eventAggregator) : base(eventAggregator)
        {

        }
        public Button1StateClass()
        {

        }
        }
        public class Button2StateClass : IItem
        {
              public VisibilityStates Visibility { get => VisibilityStates.Button2; }
              [Browsable(true)]
              [Display(Order = 2, Name = "Object2", GroupName = "Objects", ResourceType typeof(Resources.DisplayNames), AutoGenerateField = true)]

             public ButtonViewModel Button2 { get; set; }
 public Button2StateClass(IEventAggregator eventAggregator) : base(eventAggregator)
        {

        }
        public Button2StateClass()
        {

        }
        }
like image 75
Oleg Bondarenko Avatar answered Aug 08 '26 02:08

Oleg Bondarenko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!