Telerik Forums
UI for WPF Forum
3 answers
164 views

Hello,

I cannot get a C# enumeration property based on dynamically created DefineEnum call to show up as popup on a PropertyGrid.  I've tried several things but nothing worked.  Also, I am dynamically creating the PropertyDefinition items instead of statically defining anything via XAML.

Here is the basic code to load the property definitions:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    PropertyDefinitionCollection properties = EditorPropertyGrid.PropertyDefinitions;
 
    List<KeyValueBase> testList = new List<KeyValueBase>();
 
    TestEnumKeyValue first = new TestEnumKeyValue() { Key = "Static Enum Prop", Value = TestEnum.test3 };
    testList.Add(first);
    properties.Add(new PropertyDefinition()
    {
        DisplayName = first.Key,
        Binding = new Binding("Value") { Source = first }
    });
 
    DynamicEnumBuilder _enums = new DynamicEnumBuilder();
    _enums.BuildDictionaries();
    Type dynamicEnum = _enums.getEnum("Employee", "Status");
     
    EnumKeyValue second = new EnumKeyValue() { Key = "Dynamic Enum Prop", Value = Enum.Parse(dynamicEnum, "PartTime")};
    testList.Add(second);
    properties.Add(new PropertyDefinition()
    {
        DisplayName = second.Key,
        Binding = new Binding("Value") { Source = second }
    });
 
    // ************************
 
    EditorPropertyGrid.Item = testList;
}

Here are the key value pair definitions:

enum TestEnum
{
    test1,
    test2,
    test3
}
 
class KeyValueBase
{
 
}
 
class TestEnumKeyValue : KeyValueBase
{
    public string Key { get; set; }
    public TestEnum Value { get; set; }
}
 
class EnumKeyValue : KeyValueBase
{
    public string Key { get; set; }
    public object Value { get; set; }
}

 

Here is the XAML:

<Grid x:Name="EditorGrid">
    <telerik:RadPropertyGrid x:Name="EditorPropertyGrid" Margin="10,10,10,10" DescriptionPanelVisibility="Collapsed" SearchBoxVisibility="Collapsed" AutoGeneratePropertyDefinitions="False" NestedPropertiesVisibility="Visible" AutoGenerateBindingPaths="False" SortAndGroupButtonsVisibility="Collapsed" />
</Grid>

 

And here is how I generate the dynamic enum:

class DynamicEnumBuilder
    {
        public Dictionary<string, Dictionary<string, Type>> _enumDictionary = new Dictionary<string, Dictionary<string, Type>>();
 
        public void BuildDictionaries()
        {
            Dictionary<string, Dictionary<string, List<ValuePair>>> _rawDictionary = new Dictionary<string, Dictionary<string, List<ValuePair>>>();
            _rawDictionary["Employee"] = new Dictionary<string, List<ValuePair>>();
            _rawDictionary["Employee"]["Status"] = new List<ValuePair>();
            _rawDictionary["Employee"]["Status"].Add(new ValuePair() { Name = "FullTime", StoredValue = "1" });
            _rawDictionary["Employee"]["Status"].Add(new ValuePair() { Name = "PartTime", StoredValue = "2" });
            _rawDictionary["Employee"]["Status"].Add(new ValuePair() { Name = "Retired", StoredValue = "3" });
            BuildValueDictionary(_rawDictionary);
        }
 
        private void BuildValueDictionary(Dictionary<string, Dictionary<string, List<ValuePair>>> _rawDictionary)
        {
            // Get the current application domain for the current thread.
            AppDomain currentDomain = AppDomain.CurrentDomain;
 
            //// Create a dynamic assembly in the current application domain,
            //// and allow it to be executed ONLY, NOT to be saved on disk!
            AssemblyName aName = new AssemblyName("TempAssembly");
            AssemblyBuilder ab = currentDomain.DefineDynamicAssembly(
                aName, AssemblyBuilderAccess.Run);
 
            // Define a dynamic module in "TempAssembly" assembly. For a single-
            // module assembly, the module has the same name as the assembly.
            ModuleBuilder mb = ab.DefineDynamicModule(aName.Name);
 
            foreach(var fieldEntry in _rawDictionary)
            {
                Dictionary<string, Type> valueTableDic = null;
                if (!_enumDictionary.ContainsKey(fieldEntry.Key))
                {
                    valueTableDic = new Dictionary<string, Type>();
                    _enumDictionary.Add(fieldEntry.Key, valueTableDic);
                }
                else
                {
                    valueTableDic = _enumDictionary[fieldEntry.Key];
                }
 
                Dictionary<string, List<ValuePair>> rawEnumDict = fieldEntry.Value;
                foreach (var fieldEnum in rawEnumDict)
                {
                    // Define a public enumeration with the name "Elevation" and an
                    // underlying type of Integer.
                    EnumBuilder eb = mb.DefineEnum(fieldEnum.Key+"Enum", TypeAttributes.Public, typeof(int));
 
                    // build the enumerations
                    List<ValuePair> values = fieldEnum.Value;
                    foreach (var valuePair in values)
                    {
                        eb.DefineLiteral(valuePair.Name, int.Parse(valuePair.StoredValue));
                    }
                    // Create the type and save the assembly.
                    Type dynamicEnum = eb.CreateType();
 
                    // now put it in the value dictionary
                    valueTableDic[fieldEnum.Key] = dynamicEnum;
                }
            }
        }
 
        public Type getEnum(String tablename, String fieldname)
        {
            Type result = null;
            if (_enumDictionary.ContainsKey(tablename))
            {
                Dictionary<string, Type> fieldDict = _enumDictionary[tablename];
                if (fieldDict.ContainsKey(fieldname))
                {
                    result = fieldDict[fieldname];
                }
            }
            return result;
 
        }
    }

 

Basically, I want the dynamic Enum to have a popup like the static Enum, instead of PropertyGrid rendering it as a string.

Any help will be deeply appreciated!

Thanks in advance!

Martin Ivanov
Telerik team
 answered on 17 Jun 2020
1 answer
101 views

I've been testing the chart using bitmap rendering and am pleased with the performance so far. I have some questions regarding optimization. I am creating a simple line chart and am using a ScatterLineSeries, which seems to be the best match. The number of series may change, but the data itself will not change.

1. Is it possible to directly bind to or use arrays instead of arrays of objects? For example, I have 1 million data points that are stored in two arrays: one for X and one for Y. Is there any way to use the data as-is without creating intermediate classes?

2. The chart appears to create a ScatterDataPoint for each of my points. I directly added ScatterDataPoint objects to avoid creating an intermediate class, which worked. However, is there no way to specify an initial capacity? With one million points, isn't the collection going to be constantly resizing?

 

Martin Ivanov
Telerik team
 answered on 17 Jun 2020
3 answers
328 views

Hello guys,

I'd like to make a customizable editor with a button like modal style, but what I want is to reset the value when clicked.

For example, Property1 = "A".

In the editor, I change the Property1 value to "B" and when I click on the reset button, it resets to "A".

I can do it with a simple textbox and button, but it's not easy to implement it with a property grid.

Can you help me please?

Dinko | Tech Support Engineer
Telerik team
 answered on 17 Jun 2020
3 answers
661 views

I have modified the control template of TabbedWindow. But I cant find the actual tab ("handle"). How/where can I set Corenrradius="x"?

 

Robert
Top achievements
Rank 1
Veteran
 answered on 17 Jun 2020
4 answers
261 views
I turned on filtering and the default size it too large.  How can I change this size?
Tom
Top achievements
Rank 1
 answered on 16 Jun 2020
1 answer
152 views

Hello,

Using a WPF PropertyGrid. and having a problem with using Editor Attributes in combination with a nested property.  Basically, all property definitions with Editor Attributes defined at the root will work fine, however nested property definitions with Editor Attributes renders with nothing in it.  The attached file shows the problem.

Here is the code which generates the property definitions:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    PropertyDefinitionCollection properties = EditorPropertyGrid.PropertyDefinitions;
 
    ObservableCollection<object> testList = new ObservableCollection<object>();
 
    UserDefinedEnumKeyValue first = new UserDefinedEnumKeyValue() { Key = "Custom Enum Control Prop", Value = new UserDefinedEnum() { Item = "UD3", Items = { "UD1", "UD2", "UD3", "UD4" } } };
    testList.Add(first);
    properties.Add(new PropertyDefinition()
    {
        DisplayName = first.Key,
        Binding = new Binding("Value") { Source = first }
    });
 
    ParentKeyValue item = new ParentKeyValue() { ChildList = new List<KeyValueBase>() };
    testList.Add(item);
    PropertyDefinition parentPropertyDefinition = new PropertyDefinition()
    {
        DisplayName = item.Key,
        Binding = new Binding("Value") { Source = item }
    };
    properties.Add(parentPropertyDefinition);
    PropertyDefinitionCollection nestedProperties = parentPropertyDefinition.NestedProperties;
 
    UserDefinedEnumKeyValue second = new UserDefinedEnumKeyValue() { Key = "Custom Enum Control Prop nested", Value = new UserDefinedEnum() { Item = "UD3", Items = { "UD1", "UD2", "UD3", "UD4" } } };
    testList.Add(second);
    nestedProperties.Add(new PropertyDefinition()
    {
        DisplayName = second.Key,
        Binding = new Binding("Value") { Source = second }
    });
 
    EditorPropertyGrid.Item = testList;
}

 

Here are the model classes:

abstract class KeyValueBase
{
    public string Key { get; set; }
    public abstract void SetValue(string value);
 
}
 
class UserDefinedEnum : INotifyPropertyChanged
{
    private List<string> _items = new List<string>();
    public List<string> Items
    {
        get
        {
            return this._items;
        }
        //set NOTE not used for one way binding
        //{
        //    if (this._items != value)
        //    {
        //        this._items = value;
        //        this.OnPropertyChanged("Items");
        //    }
        //}
    }
 
    private string _item;
    public string Item
    {
        get
        {
            return this._item;
        }
        set
        {
            if (this._item != value)
            {
                this._item = value;
                this.OnPropertyChanged("Item");
            }
        }
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
 
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
 
class UserDefinedEnumKeyValue : KeyValueBase
{
    [Telerik.Windows.Controls.Data.PropertyGrid.Editor(typeof(EnumControl), Telerik.Windows.Controls.Data.PropertyGrid.EditorStyle.None)]
    public UserDefinedEnum Value { get; set; }
    public override void SetValue(string value)
    {
 
    }
}
 
class ParentKeyValue : KeyValueBase
{
    public string Value { get; set; }
    public List<KeyValueBase> ChildList { get; set; }
    public override void SetValue(string value)
    {
 
    }
}

 

And here is the XAML for the EnumControl:

<UserControl x:Class="TelerikWpfApp002.EnumControl"
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">
    <Grid>
        <telerik:RadComboBox SelectedValue="{Binding Item, Mode=TwoWay}" ItemsSource="{Binding Items, Mode=OneWay}" />
    </Grid>
</UserControl>

 

Thank you in advance for any help offered...

Vladimir Stoyanov
Telerik team
 answered on 16 Jun 2020
5 answers
773 views

Hello,

 

We have a desktop based WPF application that is published via RDS. Randomly throughout the day the application crashes with below exception. The error is random and the user of the application or the development\support team of the application is unable to recreate this at will. Any insights regarding this would be helpful. Thank you in advance!

 

Exception

******************************************

Application: ntierHealth.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.NullReferenceException
   at Telerik.Windows.Controls.WindowHost.GetGlobalMousePosition(System.Windows.UIElement, System.Windows.Input.MouseEventArgs)
   at Telerik.Windows.Controls.InternalWindow.DragBehavior.OnElementMouseLeftButtonUp(System.Object, System.Windows.Input.MouseButtonEventArgs)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(System.Object, System.Windows.RoutedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(System.Object, System.Windows.RoutedEventArgs, Boolean)
   at System.Windows.UIElement.ReRaiseEventAs(System.Windows.DependencyObject, System.Windows.RoutedEventArgs, System.Windows.RoutedEvent)
   at System.Windows.UIElement.OnMouseUpThunk(System.Object, System.Windows.Input.MouseButtonEventArgs)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(System.Object, System.Windows.RoutedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(System.Object, System.Windows.RoutedEventArgs, Boolean)
   at System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject, System.Windows.RoutedEventArgs)
   at System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs)
   at System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs, Boolean)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs)
   at System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr, System.Windows.Input.InputMode, Int32, System.Windows.Input.RawMouseActions, Int32, Int32, Int32)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr, MS.Internal.Interop.WindowMessage, IntPtr, IntPtr, Boolean ByRef)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
   at System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame)
   at System.Windows.Application.RunDispatcher(System.Object)
   at System.Windows.Application.RunInternal(System.Windows.Window)
   at System.Windows.Application.Run(System.Windows.Window)
   at Mdrx.PM.Client.Shell.App.Main()

******************************************

Kalin
Telerik team
 answered on 16 Jun 2020
2 answers
646 views

Hello,

First, I'm loading a PropertyGrid with dynamically generated PropertyDefintions at run-time, instead of hard coded XAML.  Second, for one PropertyGrid entry, I'm trying to load a Combobox whose model includes both a value and the list of items to show in the Combobox.  Unfortunately when I try to do this, I just get a blank Combobox (nothing in either the entry or the dropdown list) and an error:

System.Windows.Data Error: 40 : BindingExpression path error: 'Items' property not found on 'object' ''ObservableCollection`1' (HashCode=35225966)'. BindingExpression:Path=Items; DataItem='ObservableCollection`1' (HashCode=35225966); target element is 'RadComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')

 

 

So obviously XAML does not "see" Items from the model, but I thought I had everything defined properly (see code below).  So I'm missing something somewhere.  Or maybe something is not structured right.  I've looked at several example projects given in this forum, but nothing works or the sample does not fit what I'm trying to do.

The goal is to emulate an Enum but make it dynamic by loading the Comboxbox with dynamically generated lists, and I want both the entry and the list of items to be dynamically generated in the model.  Any suggestions would be welcome!!

Thanks in advance

Here is where the property definitions are being loaded

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    PropertyDefinitionCollection properties = EditorPropertyGrid.PropertyDefinitions;
 
    ObservableCollection<object> testList = new ObservableCollection<object>();
 

           // WORKS

    TestEnumKeyValue first = new TestEnumKeyValue() { Key = "Static Enum Prop", Value = TestEnum.test3 };
    testList.Add(first);
    properties.Add(new PropertyDefinition()
    {
        DisplayName = first.Key,
        Binding = new Binding("Value") { Source = first }
    });
 

           // DOES NOT WORK

    ComboListKeyValue third = new ComboListKeyValue() { Key = "List Prop", Value = "A3" };
    testList.Add(third);
    properties.Add(new PropertyDefinition()
    {
        DisplayName = third.Key,
        Binding = new Binding("Value") { Source = third } ,
        EditorTemplate = (DataTemplate)EditorGrid.Resources["ComboBoxTemplate"]
    });
 
    EditorPropertyGrid.Item = testList;
}

 

Here is the model

enum TestEnum
{
    test1,
    test2,
    test3
}
 
abstract class KeyValueBase
{
    public string Key { get; set; }
}
 
class TestEnumKeyValue : KeyValueBase
{
    public TestEnum Value { get; set; }
}
 
class ComboListKeyValue : KeyValueBase, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _value;
    private List<string> _values;
 
    public ComboListKeyValue()
    {
        _values = new List<string>() // list for combobox dynamically generated here
            {
                "A1",
                "A2",
                "A3",
                "A4"
            };
    }
    public string Value
    {
        get { return this._value; }
        set
        {
            if (value != this._value)
            {
                this._value = value;
                this.OnPropertyChanged("Value");
            }
        }
    }
 
    public List<string> Items
    {
        get
        {
            return _values;
        }
        set
        {
            _values = value;
        }
    }
 
    protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, args);
        }
    }
 
    private void OnPropertyChanged(string propertyName)
    {
        this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }
}

 

And here is the XAML

<Grid x:Name="EditorGrid">
    <Grid.Resources>
        <DataTemplate x:Key="ComboBoxTemplate">
            <telerik:RadComboBox ItemsSource="{Binding Items, Mode=OneWay}" SelectedValue="{Binding Value}"/>
        </DataTemplate>
    </Grid.Resources>
    <telerik:RadPropertyGrid x:Name="EditorPropertyGrid" Margin="10,10,10,10" DescriptionPanelVisibility="Collapsed" SearchBoxVisibility="Collapsed" AutoGeneratePropertyDefinitions="False" NestedPropertiesVisibility="Visible" AutoGenerateBindingPaths="False" SortAndGroupButtonsVisibility="Collapsed" />
</Grid>

 

Thanks!

John
Top achievements
Rank 1
Veteran
 answered on 16 Jun 2020
2 answers
348 views

Hello,     

 

I'm using the RadCartesianChart to display a dynamic number of series using two y-axis. I'd like to set the style of the vertical axis title. Any help would be appreciated. 

When I have one y-axis, I can do this:

<telerik:RadCartesianChart.VerticalAxis>
   <telerik:LinearAxis Minimum="0" x:Name="verticalAxis"                                     
                         HorizontalLocation="Left"
                         MajorTickStyle="{StaticResource tickStyle}"
                         LineThickness="1.5"
                         LineStroke="Gray"
                         LabelStyle="{StaticResource axisLabelStyle}" >
      <telerik:LinearAxis.Title>
         <TextBlock FontWeight="Bold" FontSize="13" x:Name="txtYAxisTitle"/>
      </telerik:LinearAxis.Title>
   </telerik:LinearAxis>
</telerik:RadCartesianChart.VerticalAxis>

 

But Since I can only create one y-axis this way, I can't do it this way. Instead, I have created two y-axis dynamically. When I do that, I don't know how to set the style of the title (ie. txtYAxisTitle from above). This is what I have that isn't working:

LinearAxis verticalAxisOne = new LinearAxis();
verticalAxisOne.Style = Resources["AxisTitleStyle"] as Style;
Denin
Top achievements
Rank 1
Veteran
 answered on 15 Jun 2020
3 answers
211 views
            <telerikNavigation:RadPanelBar Orientation="Horizontal" Height="100"  HorizontalAlignment="Stretch">
                <telerikNavigation:RadPanelBarItem Header="Photo" >
                </telerikNavigation:RadPanelBarItem>
                <telerikNavigation:RadPanelBarItem Header="Page">
                    <ctrl:ctrl />
                </telerikNavigation:RadPanelBarItem>
                <telerikNavigation:RadPanelBarItem Header="Cover>
                    <ctrl:ctrl />
                </telerikNavigation:RadPanelBarItem>
            </telerikNavigation:RadPanelBar>

From the code above, if the content inside the "Page" RadPanelBarItem is too long, the scrollbar will appear.
But this scrollbar appear in RadPanelBar but not that particular PanelBarItem itself.
And if you can want to click "Cover" RadPanelBarITem, you got to scroll to the end of the RadPanelBar to see it.

So, is there anyway to make the scrollbar appear inside the RadPanelBarItem itself but not in RadPanelBar.
Besides, the scrollbar located at top, it block the appearance of Header in RadPanelBarItem.
Can make it locate at bottom instead? More make sense.
Vladimir Stoyanov
Telerik team
 answered on 15 Jun 2020
Narrow your results
Selected tags
Tags
+? more
Top users last month
Rob
Top achievements
Rank 3
Iron
Iron
Iron
Atul
Top achievements
Rank 1
Iron
Iron
Iron
Alexander
Top achievements
Rank 1
Veteran
Iron
Serkan
Top achievements
Rank 1
Iron
Shawn
Top achievements
Rank 1
Iron
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Rob
Top achievements
Rank 3
Iron
Iron
Iron
Atul
Top achievements
Rank 1
Iron
Iron
Iron
Alexander
Top achievements
Rank 1
Veteran
Iron
Serkan
Top achievements
Rank 1
Iron
Shawn
Top achievements
Rank 1
Iron
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?