This is a migrated thread and some comments may be shown as answers.

Custom Enum Dropdown

24 Answers 556 Views
PropertyGrid
This is a migrated thread and some comments may be shown as answers.
Andrew
Top achievements
Rank 1
Andrew asked on 10 Apr 2013, 07:46 PM
Is there a way to customize the Enum dropdown list for a field?  We have different permission settings for our applications, and we have to limit options for some users.  An Example would be to have the following code:

Enum Produce
Apples
Oranges
Pears
Peaches
End Enum

Where we can set the 'Produce' field for some users to be able to see and select Apples and Oranges only, while others can  see and select the full list.

I have been directed to this article: http://www.telerik.com/help/wpf/radcombobox-howto-enable-disable-radcombobox-items.html, but that deals with setting it up with Xaml.  I need to change the list on the fly at runtime, and have accessed the RadComboBox with this line of code:

ComboBoxItems = RadPropertyGrid1.ChildrenOfType(Of RadComboBox)()

But now that I have it, how can I manipulate the list?  I have autobinding on, so when I try to clear or set the items manually, I get the error:

"Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead."

24 Answers, 1 is accepted

Sort by
0
Maya
Telerik team
answered on 11 Apr 2013, 06:49 AM
Hello Andrew,

I would recommend you to run through this forum thread and the sample attached there. Although it is for RadGridView, the idea and implementation should be equal. 

Kind regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Andrew
Top achievements
Rank 1
answered on 11 Apr 2013, 02:09 PM
Hello Maya,

I combed through both examples in the thread, and it appears that it is too different from what I want to do.  That example dealt with manually binding elements (autogenerate = "false") and used a list of instanced objects.  I'm trying to hide Enum values (that were autogenerated) without messing too much with the binding of the original property.

Basically, I want to autogenerateproperty, go into at runtime and manipulate the default Enum of a radcombobox by removing/hiding some of the dropdown items.


0
Maya
Telerik team
answered on 16 Apr 2013, 12:54 PM
Hello Andrew, 

I might be missing something, but in the first project attached in the forum thread, the whole logic is handled with binding to a property "IsFree" and the items in the combo are autogenerated. Could you clarify why this approach is not suitable for your scenario ?
Furthermore, how do you bind the property grid and change its Item ? Would it not be possible to update the source for the combo box while changing the item ? 

Regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Andrew
Top achievements
Rank 1
answered on 16 Apr 2013, 01:15 PM
The difference is the isFree property is bound to a list of objects, rather than an Enumeration type.  I've tried building a list of enumeration values, but the dropdown was blank, although it had the correct number of slots (Say I have a list of 2 enumeration values, there were 2 blank choices in the dropdown.)
0
Andrew
Top achievements
Rank 1
answered on 16 Apr 2013, 07:09 PM
To further explain, I put together the following code, modifying the first example in that forum thread.

In this, I have a business class with an enumeration of Produce with Fruit, Vegetables, Meat, Dairy and Grains as options.  I have defined a list with only dairy, grains, and Vegetables.  And try to set the radcombobox.itemsource = limitedlist.  It shows the right number of options, but the text fields are blank.

<Window x:Class="MainWindow"
        Title="MainWindow" Height="350" Width="525">
        <Grid>
        <telerik:RadPropertyGrid Margin="0,37,0,0" Name="RadPropertyGrid1" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="96,6,0,0" Name="tStoreName" VerticalAlignment="Top" Width="252" />
        <Label Content="My Store Name" Height="28" HorizontalAlignment="Left" Margin="0,6,0,0" Name="Label1" VerticalAlignment="Top" />
    </Grid>
</Window>

Imports System.Reflection
Imports Telerik.Windows.Controls.Data.PropertyGrid
Class MainWindow
    Public MyStore As New GroceryStore
    Public LimitedProduceList As New List(Of GroceryStore.ProduceTypes)
 
    Public Sub New()
 
        ' This call is required by the designer.
        InitializeComponent()
 
        ' Add any initialization after the InitializeComponent() call.
        Me.RadPropertyGrid1.Item = MyStore
 
        LimitedProduceList.Add(GroceryStore.ProduceTypes.Dairy)
        LimitedProduceList.Add(GroceryStore.ProduceTypes.Grains)
        LimitedProduceList.Add(GroceryStore.ProduceTypes.Vegetables)
 
    End Sub
 
    Private Sub RadPropertyGrid1_FieldLoaded(sender As System.Object, e As Telerik.Windows.Controls.Data.PropertyGrid.FieldEventArgs) Handles RadPropertyGrid1.FieldLoaded
        'warning!  You can't update visibilities here.  The internal field control cannot handle the refresh until all field loaded events are called.
        Dim MyRadComboBox As RadComboBox = Nothing
        Try
            Dim requiredPropertyDefinition = Me.RadPropertyGrid1.PropertyDefinitions.FirstOrDefault(Function(p) p.DisplayName = "MainProduce")
            Dim propertyGridField = Me.RadPropertyGrid1.ChildrenOfType(Of PropertyGridField)().FirstOrDefault(Function(t) t.DataContext Is requiredPropertyDefinition)
            MyRadComboBox = TryCast(propertyGridField.Content, RadComboBox)
 
            MyRadComboBox.ItemsSource = LimitedProduceList
 
        Catch ex As Exception
        End Try
    End Sub
 
End Class
 
Public Class GroceryStore
    Public Property Name As String
    Public Property MainProduce As ProduceTypes
 
    Public Enum ProduceTypes As Long
        Fruit
        Vegetables
        Meat
        Dairy
        Grains
    End Enum
 
End Class

0
Maya
Telerik team
answered on 17 Apr 2013, 07:11 AM
Hi Andrew,

Such behavior can be observed when combo box cannot display the value from the source. Can you try setting DisplayMemberPath property and verify whether it is visualized properly ?  

Greetings,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Andrew
Top achievements
Rank 1
answered on 17 Apr 2013, 07:47 PM
Maya,

I'm not familiar with setting the DisplayMemberPath property.  Nor do I understand what you mean by if it is visualized properly.  I checked the DisplayMemberPath and it's set to "DisplayName" by default.  I tried changing it, and nothing changed, but I really don't know what to set the value to.

The main error I can see is that I'm attaching a list of Enumeration values to a radcombobox, which is binded to a property with a type of just a single enumeration value. (not a list).


I appreciate your help to this point, but I'm still not sure we're trying addressing the same issue.  Just to recap, I'm trying to get a property (Produce) of type (ProduceType), which is defined as an enumeration (with values 'Fruit', 'Vegetables', 'Meat', 'Dairy' and 'Grains') to display only a select portion of the enumeration values in the dropdown(only 'meat' and 'dairy'), even though the property is autogenerated and bound to the property (Produce). 

In the example I provided, I doubt the method I used is ideal for what I want to do.  It's just my best guess on how it can be done. 

Thanks!
Andrew

0
Accepted
Maya
Telerik team
answered on 19 Apr 2013, 11:19 AM
Hello Andrew,

I am attaching a project that might illustrate a similar scenario to yours. Could you take a look at it and update it so that it meets your exact requirements and let me know how to modify it on my side ? 

Greetings,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Andrew
Top achievements
Rank 1
answered on 19 Apr 2013, 07:27 PM
Maya,

Thanks! That seems to do the trick.  I had a problem opening the project, as it wasn't compatible with my version of visual studio (2010).  But I was able to extract the code, and run it.  The key appears to be in either redefining the PropertyDefinition as a lookupPropertyDefinition, and resetting the binding and itemsource at the same time.

Sample VB code:
For n As Integer = 1 To Me.RadPropertyGrid1.PropertyDefinitions.Count
           If RadPropertyGrid1.PropertyDefinitions(n - 1).DisplayName = "MainProduce" Then
               RadPropertyGrid1.PropertyDefinitions(n - 1) = New LookupPropertyDefinition With { _
                   .Binding = New Binding("MainProduce"),
                   .ItemsSource = New List(Of GroceryStore.ProduceTypes)() From {GroceryStore.ProduceTypes.Dairy, GroceryStore.ProduceTypes.Grains}}
 
           End If
       Next
0
Andrew
Top achievements
Rank 1
answered on 22 Apr 2013, 08:39 PM
There appears to be a glitch with LookupPropertyDefinitions not clearing when the propertygrid item is disposed and reset:

Propertygrid1.item = nothing
Propertygrid1.item = new Item

If I run the above code, all lookuppropertydefinitions are retained, while regular propertydefinitions are cleared and reset.

I need to manually call out:

Propertygrid1.item = nothing
Propertygrid1.PropertyDefinitions.clear()
Propertygrid1.item = new Item

It's not a problem now that I have it fixed, but it may cause other issues I'm not aware of.
0
Maya
Telerik team
answered on 24 Apr 2013, 07:52 PM
Hello Andrew,

Actually, that would be a kind of an expected behavior. When AutogeneratePropertyDefinition is true and the item is changed, we clear only those properties whose IsAutogenerated property is true. This is not the case with the lookup property definition since it is manually created in the event.
The approach with clearing the PropertyDefinitions is appropriate or you can try to remove just the lookup property definition, property grid will take care of the rest. Another hint would be not to set the Item to null. There is actually no need for doing this, just changing the item property should do the job.
Let me know in case you have further problems. 

Regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Andrew
Top achievements
Rank 1
answered on 30 Apr 2013, 02:26 PM
Okay, so this solution works for simple dropdowns.  But no longer allows for multiple selection (flag enums)  Is there a way to do this while keeping flag enums?
0
Maya
Telerik team
answered on 30 Apr 2013, 02:59 PM
Hello Andrew,

Could you clarify a bit - what is not working in this case ?  

Regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Andrew
Top achievements
Rank 1
answered on 30 Apr 2013, 03:02 PM
By implementing the solution from your example, I'm adding a list of Enum values to the field.  This is fine for a standard Enum.  But when I want implement an Enum with the Flags attribute, so I can select multiple values, this doesn't appear to work in the example, and I'm not sure how to work around it.
0
Maya
Telerik team
answered on 30 Apr 2013, 03:45 PM
Hi Andrew,

I mgiht be missing something here, but do you expect to have a flag enum editor as illustrated in this article ? If so, you can try following the approach explained there by createing editor template for a particular property definition.   

Greetings,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Andrew
Top achievements
Rank 1
answered on 30 Apr 2013, 03:52 PM
Yes,

That's my intention.  But while specifying custom lists by adding a LookupPropertyDefinition at runtime.  So you're saying I can add an editor template here, and it should work?

For n As Integer = 1 To Me.RadPropertyGrid1.PropertyDefinitions.Count
           If RadPropertyGrid1.PropertyDefinitions(n - 1).DisplayName = "MainProduce" Then
               RadPropertyGrid1.PropertyDefinitions(n - 1) = New LookupPropertyDefinition With { _
                   .Binding = New Binding("MainProduce"),
                   .ItemsSource = New List(Of GroceryStore.ProduceTypes)() From {GroceryStore.ProduceTypes.Dairy, GroceryStore.ProduceTypes.Grains}}
  
           End If
       Next

That would lead me to my next question.  I'm not yet comfortable with Xaml, or C#, and have yet to find an adequate example that clearly indicates how I can mix and match editor templates at runtime.  I've found work-arounds modifying the FieldInfo directly (extracting the textboxes, radcomboboxes, etc and modifying them in codebehind) to get what I need, and the results so far are satisfactory.  So if I need to set the editor template to a flag enum template at runtime, how would i do that using the above code as a reference?
0
Maya
Telerik team
answered on 30 Apr 2013, 04:40 PM
Hello Adnrew,

If you create a DataTemplate in the Resources and give it a key, they you can assign the EditorTemplate property of the property definitions in a way similar to:
myPropertyDefinition.EditorTemplate = (DataTemplate)this.Resources["MyEditorTemplate"];

All the best,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Andrew
Top achievements
Rank 1
answered on 01 May 2013, 03:00 PM
Maya,

Can you let me know what I'm doing wrong? I define the template here.  Then call the code you provided in the background, and it returns a value of null.

<Grid.Resources>
    <DataTemplate x:Key="MyFlagEnumTemplate">
        <telerik:FlagEnumEditor  >
        </telerik:FlagEnumEditor>
    </DataTemplate>
</Grid.Resources>
0
Andrew
Top achievements
Rank 1
answered on 01 May 2013, 03:16 PM
Maya, 

My apologies, my last question comes because I'm still learning Xaml, I put the template in grid.resources when I needed to put it in window.resources.  I have a FlagEnumEditor returned now, but it doesn't appear to allow me to select anything.  I'm redefining the property definition as follows, where the new item source is a list of enum values (in this case, a list of flagged Enum values).  When I run this code the editor is blank, and has no items.

RadPropertyGrid1.PropertyDefinitions.Insert(n - 1, new LookupPropertyDefinition {
    Binding = new Binding(PropertyName),
    ItemsSource = TowerDefinition.GetPropertyList(ListID),
    GroupName = GroupName,
    Description = Description,
    OrderIndex = OrderIndex,
    DisplayName = DisplayName,
    Visibility = Visibility,
    EditorTemplate = (DataTemplate)this.Resources("MyFlagEnumTemplate")
})
0
Maya
Telerik team
answered on 01 May 2013, 09:06 PM
Hello Andrew,

Actually, if you define Key attribute for the Grid, you can work with its Resources as well. So, if the key is "MyGrid", you can find it as: this.MyGrid.Resources[...].
As for the current problem, you need to create regular PropertyDefinition (no need to to have LookupPropertyDefinition, since you will place FlagEnumEditor as an editor). You have to set the source to the FlagEnumeEditor, rather then the property definition. 

Regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Andrew
Top achievements
Rank 1
answered on 01 May 2013, 09:54 PM
Maya,

Can you clarify what you mean by setting the source to the FlagEnumEditor, rather then the property definition? Did you mean Itemsource?  I wasn't setting the source on this (and admittedly, It was coming back null, which was confusing).  

Does the LookupPropertyDefinition have auto-define it's source, that's independent of it's binding?

Will your approach work for a property that is defined as a single Enum, and yet have a custom source list of items?

0
Maya
Telerik team
answered on 03 May 2013, 02:41 PM
Hi Andrew,

Could you please take a look at the sample attached and let me know whether it corresponds to your sceanario ? Is that the behavior that you want to achieve ?  

Regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Andrew
Top achievements
Rank 1
answered on 03 May 2013, 06:39 PM
Maya,

I don't see in the attached example how you can changed the position list from displaying all positions (GK,DF,MF,FW) for player 1 (Fernando Torres) and displaying select positions (GK,FW) for Player 2 (Bob).  

It seems like I can 1) display custom lists using a lookupPropertyDefinition (previous example from April 19) OR 2) display a static list of flag enum values (Example from today).  Not both.  If I could combine them to display a custom list of flag enum values, I'd be set.

Thanks,
Andrew
0
Maya
Telerik team
answered on 08 May 2013, 09:41 PM
Hello Andrew,

What you can try is to handle Loaded event of FlagEnumEditor and remove the items you want:

XAML:
<telerik:FlagEnumEditor Value="{Binding Position}" EnumType="my:Position" Loaded="FlagEnumEditor_Loaded"/>
 
Code-behind:
 
private void FlagEnumEditor_Loaded(object sender, RoutedEventArgs e)
        {
            var enumEditor = sender as FlagEnumEditor;
 
            var player = enumEditor.DataContext as Player;
            if (player != null && player.Name.Contains("Fernando"))
            {
                enumEditor.EnumItemsSource.RemoveAt(0);
            }
        }
 
Will that approach meet your requirements ? 

Regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Tags
PropertyGrid
Asked by
Andrew
Top achievements
Rank 1
Answers by
Maya
Telerik team
Andrew
Top achievements
Rank 1
Share this question
or