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.
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()
{
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With