如何在WPF中以编程方式添加或删除DisplayAttribute

时间:2019-11-05 13:02:10

标签: c# wpf

我通过以下方式在UI中创建一些项目

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

我试图做的是根据某种条件显示或隐藏这些UI元素。 我看到如果我将AutoGenerateField设置为true / false,则可以得到所需的结果,是否有某种方法可以在运行时将该值设置为true / false? (如果可能的话)

是否有另一种方法可以做到这一点?就像每次添加/删除显示属性一样。

编辑

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

    }


传递的项目是上面的Buttons.cs。

1 个答案:

答案 0 :(得分:2)

您可以为每个可见性状态创建两个已实现IItem接口的类,并根据当前可见性状态将适当的一个设置为RadPropertyGrid。但这仅适用于数量不多的可见性状态(您必须为每个状态创建单独的类)。 另一种方法是通过反射为每个属性动态设置Display属性。但是我建议您按照第一种方法使用拆分类。

            // 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()
        {

        }
        }