TeeChart in VB.Net : Subclassing SeriesXYZPoint cannot assign X axis - teechart

I have a very simple class I'm using to subclass a SeriesXYZPoint in TeeChart vb.net
Imports Steema.TeeChart.Styles
Public Class CustomSeriesXYZPoint
Inherits SeriesXYZPoint
Public Sub New(X As Double, y As Double, z As Double, color As Color, flagged As Boolean)
MyBase.New()
Me.X = X
Me.Y = y
Me.Z = z
Me.Color = color
Me.flagged = flagged
End Sub
Public flagged As Boolean
End Class
When I try to assign to the X value at "Me.X = X" I get a nullReferenceException with no InnerException, even though I can see that "Me" is not null in the constructor (as you would hope...)
What I'm doing here should be really simple, and the error message I get is totally opaque. Any help would be awesome.
Edit: I get the same error when I run
Dim thing As New SeriesXYZPoint
thing.X = someValue

The SeriesXYZPoint class is not a series type designed to be drawn in a chart. It's a class internally used to extend series functionality like Custom3D and derived. It needs a series associated to access that X property:
public class SeriesXYPoint : SeriesPoint
//...
public double X
{
get
{
return series.XValues[index];
}
//...
}
}
Instead, you may want to extend Points3D series.

Related

Why do Static Methods & Enumerations have unexpected behavior in Xamarin Forms? Objects Passed to Static Methods become null & enums are stored as int

I have been using C#/.NET/Visual Studio since 2000, but I just started working with Xamarin Forms recently. It's a pretty great platform, however I have run across a couple of issues that I cannot figure out. (I'm using Visual Studio 2017 Community). I have been researching this behavior extensively, but have had absolutely no luck in obtaining a resolution. I have created a small application which easily reproduces both of these behaviors and would greatly appreciate any expertise that would help me fix my code so it works as expected. The two issues are these:
1) After creating a custom object using new in Xamarin Forms, the object is not null. However, if that object is passed via the parameter list into a static method, it becomes null inside the method. (Note: In my sample applications I placed the static method inside the Form1 and MainPage classes. I did this only to simplify the samples. The behavior is the same when I put the static method into a separate utility class, either static class or normal class.)
2) Custom enumerations are treated as integers instead of the actual enumerated type. For example, if an instance of an enumerated type is given a value of the first item in the enumeration, its value is 0, an integer. Whereas in a Windows application, the value would be the actual enumeration value (e.g., EnumValue1), and its type would be the enumerated type. This can be a problem if one is trying to do comparisons with strings. For example, aEnum.ToString() == "EnumValue1" will return true in a Windows application, but will return false in Xamarin Forms, because aEnum.ToString() will evaluate to "0". This behavior also breaks the tenet of encapsulation in object-oriented programming, in that you aren't supposed to have to know the underlying implementation of a data type in order to properly use it.
Below is the code that reproduces the issues. There are 2 separate projects, one Windows Forms, the other Xamarin Forms. (The Xamarin Forms project was created with .NET Standard code sharing strategy). Both projects use 2 utility classes Enumerations and CustObj, where the only differences are the namespace definitions (namespace WinFormApp.Utilities and namespace XamarinFormsApp.Utilities, respectively). They both reside in a Utilities folder under their respective projects.
Windows Forms "Form1.cs"
using System.Windows.Forms;
using WinFormApp.Utilities;
namespace WinFormApp
{
partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// ENUMERATION TEST
ACustomEnumeration aCE = ACustomEnumeration.EnumValue1;
string aceStr = aCE.ToString();
// PASSING OBJECT TO STATIC METHOD
CustObj aCustObj = new CustObj();
int ii = aCustObj.i;
string ss = aCustObj.s;
Form1.Foo(aCustObj);
}
public static void Foo(CustObj custObj)
{
}
}
}
Xamarin Forms "MainPage.xaml.cs"
using Xamarin.Forms;
using XamarinFormsApp.Utilities;
namespace XamarinFormsApp
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
// ENUMERATION TEST
ACustomEnumeration aCE = ACustomEnumeration.EnumValue1;
string aceStr = aCE.ToString();
// PASSING OBJECT TO STATIC METHOD
CustObj aCustObj = new CustObj();
int ii = aCustObj.i;
string ss = aCustObj.s;
MainPage.Foo(aCustObj);
}
public static void Foo(CustObj custObj)
{
}
}
}
Utility class "Enumerations.cs"
namespace WinFormApp.Utilities (or XamarinFormsApp.Utilities)
{
public enum ACustomEnumeration
{
EnumValue1,
EnumValue2
}
class Enumerations
{
}
}
Utility class "CustObj.cs"
namespace WinFormApp.Utilities (or XamarinFormsApp.Utilities)
{
public class CustObj
{
public ACustomEnumeration _aCEMember;
public int i;
public string s;
public CustObj()
{
this.i = 99;
this.s = "Hello!";
}
}
}
When stepping through the WinFormApp in Visual Studio, one observes the following variables before the call to static method Foo:
aCE with value of EnumValue1 and Type ACustomEnumeration
aceStr with Value of "EnumValue1" and Type string
aCustObj with Type CustObj and data members:
_aCEMember with Value of EnumValue1 and Type ACustomEnumeration
i with Value of 99 and Type int
s with Value of "Hello!" and Type string
ii with Value of 99
ss with Value of Hello!
After stepping into Foo, the parameter is as expected:
custObj with Type CustObj and data members:
_aCEMember with Value of EnumValue1 and Type ACustomEnumeration
i with Value of 99 and Type int
s with Value of "Hello!" and Type string
All variables evaluate as expected. Enumerations evaluate as the actual enumerated value. The custom object is instantiated and its data members are given their appropriate initial values. When the object is passed into the static method, it is passed correctly as a reference type, and retains all of its data inside the method.
Conversely, when stepping through the XamarinFormsApp in Visual Studio, one observes the following variables before the call to static method Foo:
aCE with Value of 0 and Type int (violates encapsulation)
aceStr with Value of "0" and Type string (this demonstrates the problem with how enumerations are evaluated)
aCustObj with Type CustObj and data members:
_aCEMember with no Value or Type at all
i with no Value or Type at all
s with no Value or Type at all
ii with Value of 99
ss with Value of Hello!
After stepping into Foo, the parameter is NOT as expected:
custObj with Value of null and Type CustObj
The problems with enumerations are fairly obvious. But I am very confused as to what is really going on with the custom object. It makes no sense that when I examine an object after its instantiation, that it doesn't show its data members as being initialized. Although it is strange how variables ii and ss are actually given the correct values.
More importantly, the fact that when I pass the object into the static method, it becomes null, is really mind-boggling.
Does anyone have any ideas as to what is happenning, and how to fix it?

Can't access any of Linq methods

I'm writing a simple ApiController for getting product stocks, but I'm having a strange issue. I get the data from a method that returns a System.Linq.IQueryable (In a library), but I can't apply any of the Linq methods, like Count or ToList(). The import directive is present and doesn't report any problem. Also intellisense shows Data as System.Linq.IQueryable.
The code:
Imports System.Web.Http
Imports System.Linq
Public Class ProductSearchController
Inherits ApiController
Public Function Get(...) As IQueryable
Dim nvc As NameValueCollection = HttpUtility.ParseQueryString(Request.RequestUri.Query)
Dim sEcho As String = nvc("sEcho").ToString()
Dim iDisplayStart As Integer = CType(nvc("iDisplayStart"), Integer)
'Signature of Stock: public IQueryable Stock(...)
Dim Data = New GenericSearches().Stock(...)
Dim Count As Integer = Data.Count() 'Error Here!
Dim result = New DataTableResult With {
.sEcho = sEcho,
.iTotalRecords = Count,
.iTotalDisplayRecords = Count,
.aaData = Data.ToList() 'Error Here!
}
Return result
End Function
End Class
Also, I noticed that error correction and intellisense asks me to choose those methods from a weird Devexpress library something like DevXpress.Data.Helpers.Linq.
The non-generic IQueryable interface doesn't have extension methods of Count and ToList(). Only the generic IQueryable<T> does.
If you can modify the library to return a suitable IQueryable<T>, I suggest you do so. If you can't, you may need to call Cast<T>() or OfType<T>() to create an appropriate IQueryable<T> with the right extension methods.

Conditionally change backgroundcolor for captions in an ultragrid

I am using ultragrid 9.1. I am displaying the details as cardview. I can change the back color of the card caption by using the following property:
Ultragrid.DisplayLayout.Override.CardCaptionAppearance.BackColor = System.Drawing.Color.Red
However, I want to change the back color of the caption conditionally and not for all rows. I am unable to find the relevant property to set this.
My problem has been solved. There is no in built property that could be used to set the background color of the caption. I had to use the DrawFilter interface.
You can find more information about this interface from this link:
You should create a class that implements IUIElementDrawFilter.
In the GetPhasesToFilter method of the interface check if the element is CardCaptionUIElement and if it is return its BeforeDrawBackColor phase. Then in the DrawElement method you can draw the background using the DrawBackColor method of the drawParams argument.
Then, set the drawfilter for the ultragrid.
UltraGrid1.DrawFilter = New CustomDrawFilter()
Class CustomDrawFilter : Implements IUIElementDrawFilter
Public Function DrawElement(drawPhase As DrawPhase, ByRef drawParams As UIElementDrawParams) As Boolean Implements IUIElementDrawFilter.DrawElement
Dim row = DirectCast(drawParams.Element.GetContext(), UltraGridRow)
If (row.VisibleIndex Mod 2 = 0 And row.Selected = False) Then
drawParams.AppearanceData.BackColor = Color.Red
drawParams.DrawBackColor(drawParams.Element.RectInsideBorders)
Return True
End If
Return False
End Function
Public Function GetPhasesToFilter(ByRef drawParams As UIElementDrawParams) As DrawPhase Implements IUIElementDrawFilter.GetPhasesToFilter
If (TypeOf (drawParams.Element) Is CardCaptionUIElement) Then
Return DrawPhase.BeforeDrawBackColor
Else
Return DrawPhase.None
End If
End Function
End Class

How to retrieve strings from resource files for all the languages VB6

Is there a way to retrieve strings for all the languages available in a resource file? I just got a requirement for showing labels in 2 languages at the same time.
You've got two approaches if you want to use the standard VB6 resource files.
The first is to define each language version of the string by a range in the resource file. So say you had a class to wrap up the string like this:
'In Class clsLocalizedStrings
Public Enum StringIds
UserNameCaption = 1
PasswordCaption
OkayCaption
CancelCaption
End Enum
Public Enum LocaleIds
English = 1000
French = 2000
Spanish = 3000
End Enum
Private mLangId As LocaleIds
Public Property Get CurrentLanguge() As LocaleIds
CurrentLanguge = mLangId
End Property
Public Property Let CurrentLanguge(ByVal newVal As LocaleIds)
mLangId = newVal
End Property
Public Function GetLocalString(ByVal id As StringIds)
Dim lResStrId As Long
lResStrId = mLangId + id
GetLocalString = LoadResString(lResStrId)
End Function
You could then set the CurrentLanguge at will and fetch the string value.
The alternative way, where each language gets its own resource file, is to create an ActiveX dll project for each language. Each of these project would expose just a single class similar to the one above. Ideally, you have a default language to use as a base, and the other reference it to implement the class:
'In Class LocalizedStrings in Project DefaultResources (with its own English resource file)
Public Enum StringIds
UserNameCaption = 1
PasswordCaption
OkayCaption
CancelCaption
End Enum
Public Function GetLocalString(ByVal id As StringIds)
GetLocalString = LoadResString(id)
End Function
'In Class FrenchStrings in Project FrenchResources (with its own French resource file)
Implements DefaultResources
Public Function DefaultResources_GetLocalString(ByVal id As DefaultResources.StringIds)
DefaultResources_GetLocalString= LoadResString(id)
End Function
Then in your main application you reference these dlls and make them available in a class or module:
'In Class clsLocalization in main app project
Public Enum LocaleIds
English = 1
French = 2
Spanish = 3
End Enum
Private mLangId As LocaleIds
Private mResources() as DefaultResources
Private Sub Class_Initialize()
Redim mResources (1 to 3)
Set mResources(1) = DefaultResources.LocalizedStrings 'assumes english is default, easy to change though
Set mResources(2) = FrenchResources.FrechStrings
Set mResources(3) = SpanishResources.SpanishStrings
End Sub
Public Property Get CurrentLanguge() As LocaleIds
CurrentLanguge = mLangId
End Property
Public Property Let CurrentLanguge(ByVal newVal As LocaleIds)
mLangId = newVal
End Property
Public Function GetLocalString(ByVal id As StringIds)
GetLocalString = mResources(mLangId).GetLocalString(id)
End Function
Public Propert Get Langauge(ByVal langId As LocaleIds)
Return mResources(langId)
End Property
And this in a module:
Global Localization As clsLocalization
Thn you use it like this:
'show caption for current languge
MsgBox Localization.GetLocalString(StringIds.UserCaption)
'show caption for explicit languge
MsgBox Localization.Langauge(French).GetLocalString(StringIds.UserCaption)
MsgBox Localization.Langauge(Spanish).GetLocalString(StringIds.UserCaption)
Hope that helps!

Convert String into Class for TitleWindow

I don't know if this is possible, I am pulling the names for TitleWindows from my database as strings.
Then from my main application I have to launch the TitleWindow. So in my function I need to convert the name of the TitleWindow which is a String to a Class, because the PopUpManager accepts a Class. Below is my code.
When launching my application and trying to launch the TitleWindow I am getting the error:
Implicit coercion of a value of type String to an unrelated type Class.
I don't want to hard code the name of my popUp in the PopUpManager, that is why I am doing it like this. Any way to work around this?
public function getScreen(screenName:String):void
{
var screen_Name:Class = new Class();
screen_Name = screenName;
var popUpWindow:TitleWindow = PopUpManager.createPopUp(this, screen_Name, false) as TitleWindow;
PopUpManager.centerPopUp(popUpWindow);
}
I have had to do something very similar recently. Here is the function I wrote to do it:
//You have to provice the package signature
private var viewPackage:String = "org.bishop";
//In my case, event.type is the name of a class
var className: String = viewPackage + "." + event.type;
try{
var classRef:Class = getDefinitionByName(className) as Class;
viewNavigator.pushView(classRef);
}
catch(e:ViewError){
trace(e.message);
logger.debug(e.message);
}
Note: for the class to be created correctly, you will need to include both an import statement:
import org.bishop.Login;
and also declare a variable of the class in the code as follows:
Login;
otherwise the classes will not be available to be created.

Resources