I am passing command parameters to a command. and receiving it like this
public void SelectTestCase(object Dev)
{
try
{
_navigationStore.CurrentViewModel = new TestCaseViewModel(_navigationStore);
}
catch (Exception e)
{
}
}
in this Object Dev will be carying data related to Device. but if i do dev.DeviceName this is giving error because dev object is recieving data on runtime.
how can i use this Dev object and get data on runtime
You have the parameter specifically as a generic "object" rather than the specific class type. You need to type-cast it. Ex:
public void SelectTestCase( object Dev )
{
if( Dev is myDeviceTypeClass )
{
var tmp = (myDeviceClass)Dev;
// Now you can use as needed
MessageBox.Show( tmp.DeviceName );
}
// if you have different POSSIBLE device classes passed in,
// just test for those too.
}
Assuming that Dev is actually a fixed type then you could try to define a Device class matching the properties.
public void SelectTestCase(Device Dev)
and something like
public class Device
{
public string DeviceName {get;set;}
// other properties
}
Related
We have a customization where we are running a processing screen against customer locations. When we try to update the location in the Location cache, we are getting the following error:
Unable to cast object of type
'PX.Data.PXCache`1[PX.Objects.AR.SelectedCustomerLocation]' to type
'PX.Data.PXCache`1[PX.Objects.CR.Location]'.
Here is a simplified version of the code we are using. The ProcessLocation method is the PXProcessing delegate:
public class LocationMaint_Extension : PXGraphExtension<LocationMaint>
{
public virtual void ProcessLocation(Location loc)
{
LocationExt locExt = loc.GetExtension<LocationExt>();
locExt.UsrCustomField = "New Value";
Base.Caches<Location>().Update(loc);
}
}
We are aware that SelectedCustomerLocation derives from SelectedLocation, which derives from Location. Because of that, we would expect the above code to run successfully, since there is an inheritance present.
If we write the following code, the method succeeds, and the screen is updated successfully. However, the change we made to the custom field is not persisted to the database:
public class LocationMaint_Extension : PXGraphExtension<LocationMaint>
{
public virtual void ProcessLocation(Location loc)
{
LocationExt locExt = loc.GetExtension<LocationExt>();
locExt.UsrCustomField = "New Value";
Base.Caches<SelectedCustomerLocation>().Update(loc as SelectedCustomerLocation);
// We had this code in as well, which did not seem to help
Base.Caches<SelectedCustomerLocation>().Persist(PXDBOperation.Insert);
Base.Caches<SelectedCustomerLocation>().Persist(PXDBOperation.Update);
}
}
Any help would be greatly appreciated. Thank you.
In C# (and .NET generally), you cannot cast an object of type G<Derived> to G<Base> where G is a generic type. This is kind of a pain sometimes. In the past I have made custom methods to do this, like for a List<T> you might use something like this:
static List<TBase> Upcast<TBase, TDerived>(this List<TDerived> list)
where TDerived : TBase
{
var result = new List<TBase>();
foreach (var d in list)
{
result.Add(d);
}
return result;
}
I have 2 buttons, that both are to show a new viewmodel, but with different data passed to the viewmodel. The data is passed is not completely different, so they both inherit from the same base. Unfortunately, it seems like the data passed to the Init() method of the viewmodel loses its runtime type information on the way? Using a debugger (or code), the passed data is only recognised as the base-class - NOT the derived class that was actually constructed and passed to the ShowViewModel<>() method.
Is what im trying to do not possible?
public class BasePasser
{
}
public class PasserA : BasePasser
{
}
public class PasserB : BasePasser
{
}
public class ViewModelOne : MvxViewModel
{
// ...
private void DoSwitchViewModelA()
{
var tobepassed = new PasserA {
// ...
};
ShowViewModel<ViewModelTwo>(tobepassed);
}
private void DoSwitchViewModelB()
{
var tobepassed = new PasserB {
// ...
};
ShowViewModel<ViewModelTwo>(tobepassed);
}
}
public class ViewModelTwo : MvxViewModel
{
// ...
public async Task Init(BasePasser passed)
{
if(passed is PasserA)
{
// ...
}
else if(passed is PasserB)
{
// ...
}
else
{
// Always called/hit
throw new InvalidOperationException("Unknown data passed");
}
}
}
Showing a ViewModel in MvvmCross is actually a pretty complicated process.
When you call ShowViewModel(param) Mvx will serialize the param value into a name/value dictionary. At this point, the Type information for param is lost.
When the ViewModel is instantiated, it will eventually look for any Init methods defined on the ViewModel.
If you look in Cirrious.MvvmCross.ViewModels.MvxViewModelExtensions.CallBundleMethod() you'll see that it first looks for a method with a single parameter of type IMvxBundle. Then it looks for a single parameter that is not a simple type (like string, int, etc.)
If it finds this type, it assumes it's an object that has been serialized in the ShowViewModel() call. It then attempts to deserialize the value based on the Type of the parameter in the Init method, NOT the original type.
This is why you only see the base type, since Mvx doesn't have the type information for the initial call, and when deserializing, only sees the base type from the Init method.
The workaround is to just put all properties into a single class. Only set the ones that you need and create a discriminator property that specifies which "type" it is.
var param = new Passer { PasserType = "A", ParamA = "ValueA", ... etc. }
You also have the option of using named method arguments.
See the Init section from https://github.com/MvvmCross/MvvmCross/wiki/View-Model-Lifecycle
I am constructing a list of strings and then want to throw an exception and let the UI handle the list and create the error message for the user.
Is there a way to do that?
Exceptions contains Data property (which is a dictionary). It can be used to pass additional information:
try
{
// throw new Exception
}
catch(Exception e)
{
// whatever
e.Data["SomeData"] = new List<string>();
}
You can use the Exception.Data property to pass arbitrary data but a better (cleaner) solution would be to create your own custom exception class derived from Exception and add whatever properties you need to it.
Sample code:
public class MyException: Exception
{
public List<String> MyStrings { get; private set; }
public MyException(List<String> myStrings)
{
this.MyStrings = myStrings;
}
}
Hell guys.
I am making this project with a Server, a Client and a Class library.
In the class library (which I added to the Server and the Client as Reference), I have for example an:
string f = "not working";
public void SetString(string n)
{
f = n;
}
public string GetStr ()
{
return f;
}
I have connected the client and the server and they are working properly, also the Get method is working but the SET METHOD isn't working?? When I call the set method from the client, it doesn't set the value that I am giving!!.
HttpChannel chan = new HttpChannel();
Tic obj = (Tic)Activator.GetObject(typeof(Tic), "http://127.0.0.1:9050/MyServer");
private void Form1_Load(object sender, EventArgs e)
{
ChannelServices.RegisterChannel(chan);
}
private void button1_Click(object sender, EventArgs e)
{
string m = "working";
obj.SetString(m);
}
Again i repeat that the Get Method is working properly, but only the Set Method... and the problem is that it doesn't show me any error!!! it is just not giving the value to the string variable!!
If I understand your set up correctly you are contacting a remote http server and calling a method which sets a variable value. You then contact that http server and ask for the value back, and you are getting the original value.
I'm not sure what sort of web "server" you are hosting but most of the time, servers only instantiate their classes when called upon. So basically you are contacting a server, it instantiates whatever class containing the "f" string. You set the value. The server completes its job and kills the process. Then you contact the server again asking for the value of "f", so it instantiates everything again, which means the value would be "not working".
Have you tried using Properties instead?
public class Foo
{
public string Message {get;set;}
}
public class Bar
{
public void Boz()
{
var foo = new Foo();
foo.Message = "Working";
}
}
I'm beating my head against the wall pretty severely with this. I have several variables inside a C# console application that I would like to re-use. However, I cannot for the life of me re-use the variables in another class. I would love any help or pointers you could provide - I've searched for quite some time and I'm completely stumped.
EDIT: Yes, the variables are inside my Main function. Sorry for leaving this out.
EDIT: Heavily redacted code below. The variable values I'd like to re-use in another class are in the middle. There are more but those 3 should be sufficient for the sample. Thanks for the assistance!!!
public static class MyApp
{
static void Main(string[] args)
{
// loads XML doc
foreach (XmlNode node in nodes)
{
try
{
// does a bunch of stuff
// Parses variables from REST API
XDocument docdetailxml = XDocument.Parse(xmldoc);
XNamespace ns = docdetailxml.Root.GetDefaultNamespace();
var buid = docdetailxml.Root.Element(ns + "busid").Value;
var bname = docdetailxml.Root.Element(ns + "busname").Value;
var bcount = docdetailxml.Root.Element(ns + "buscount").Value;
// Invoke SQL connection string
// Trigger Stored Procedure and write values to database
// If needed, trigger email notification
// Close connections
}
catch (Exception e)
{
Console.WriteLine("Error encountered: " + e.Message);
// Exit the application
System.Environment.Exit(1);
}
finally
{
// Exit the application
// System.Environment.Exit(0);
}
}
}
private static void GetConnectionString()
{
throw new NotImplementedException();
}
private static void GetConnectionStrings()
{
throw new NotImplementedException();
}
}
}
you should define public property or public field
public class Student
{
public string Name {get;set;}
}
and when you want to pass value you can assign this value to property
Student st = new Student();
st.Name = "your value";
or you can use class constructor too.
If the variable denote some information about an object (like name, id, etc.) then they should be encapsulated in a class. The instance of the class (called an object) should be used to access this information.
As you already have the variables that represent an object, the next step would be to group these variables into classes. These variables are represented as properties in the class. The operations performed on these members should be available as methods. Furthermore the access modifiers decide the visibility of the members.
Going through your example, I can identify 3 variables that represent a Customer (assumption, I am not sure of the exact use case). These will form the Customer class.
class Customer
{
// You can either pass the UID through the constructor or
// expose a public setter to allow modification of the property
public Customer(string uid)
{
this.UID = uid;
}
public string UID { get; private set; }
public string Name { get; set; }
public string Count { get; set; }
}
Furthermore, the foreach loop can be split into 2 parts for resuablity
Read from the xml nodes and create a list of customers
Perform the database operations (like trigger stored procedures, write values, etc.) on the list of customers
Additionally, you can create another class that does the operations (business logic) that you are performing in the console application. This will allow you to reuse the same logic in case you move it to another application (like winforms or web service).
More information
Object oriented programming
Object oriented concepts in C#
Principles Of Object Oriented Design
I think there's a dedicated forum for struts on this site, best look there for more info.
Quick answer: the primary way of passing values from one action to another (I think you are working with struts Action classes?) is to put the values into the request or session (so, first job for you would be to read up on those topics: HttpServletRequest and HttpSession). Struts action classes do their work in the execute() method, and that method has a parameter of type HttpServletRequest. From the request you can get a handle to the session.
And both request and session offer methods getAttribute() and setAttribute(). So, to pass data from one action to another, set that data as a (request or session) attribute, then read out the attribute in the next action again.
The Program class is probably Static so you'll have to access those fields by class name instead of instance.
class Program
{
public string Name = "a name";
static void Main(string[] args)
{
Name = "Hello"; //You can't do this, compile error
Program p = new Program();
p.Name = "Hi"; //You can do this
SecondName = "Sn"; //You can do this
Program.SecondName = "Tr"; //You can do this too
}
public static string SecondName = "Peat";
}