Can't pass data between classes - c#

I am developing a Kinect application based on VS2012 using winform. After I tried several methods, I still couldn't pass value from one class to another class.
Basically I have three class, a public MainWindow(), public partial FaceTrackingViewer(), and public SkeletonFaceTracker(). The last class reside in FaceTrackingViewer() class.
In SkeletonFaceTracker(), I have the following:
public bool lastFaceTrackSucceeded { get; set; }
internal void OnFrameReady(KinectSensor kinectSensor, ColorImageFormat colorImageFormat, byte[] colorImage, DepthImageFormat depthImageFormat, short[] depthImage, Skeleton skeletonOfInterest)
{
// something else
if (this.faceTracker != null)
{
this.lastFaceTrackSucceeded = frame.TrackSuccessful; //where it's set to be true.
//something else
}
}
I also tried to change to first line to:
public bool lastFaceTrackSucceeded;
public bool LastFaceTrackSucceeded
{
get { return lastFaceTrackSucceeded; }
private set { lastFaceTrackSucceeded = value; }
}
I think the two are the same though.
In MainWindow(), I have:
public partial class MainWindow : Window
{
//some other irrelevant code snippets
private FaceTrackingViewer.SkeletonFaceTracker skeletonFaceTracker = new FaceTrackingViewer.SkeletonFaceTracker();
private void button_faceOnly_Click(object sender, RoutedEventArgs e)
{
bool faceTrackSucceeded = skeletonFaceTracker.lastFaceTrackSucceeded;
// if I use the second structure in SkeletonFaceTracker(), it should be:
// bool faceTrackSucceeded = skeletonFaceTracker.LastFaceTrackSucceeded;
if (faceTrackSucceeded == true )
{
//do something
}
}
}
However, the bool faceTrackSucceeded is always false, even if the lastFaceTrackSucceeded or LastFaceTrackSucceeded in SkeletonFaceTracker() is true. I am very confused and don't know where it went wrong.
Please note that all the video processing and face tracking actions occur in FaceTrackingViewer() class. I simply want to pass some parameters and structures to MainWindow().
Thank you

One thing first - I assume you are making the variable lastFaceTrackSucceeded public purely for testing purposes. The two ways of defining the property are functionally the same in your example.
The only other thing I can think of is that you are setting LastFaceTrackSucceeded true on a different instance of SkeletonFaceTracker. You haven't provided enough code for me to be sure about this, but if you have two (or more) instances then it can be easy to get them mixed up.

Related

Is it possible to restrict public enum values in C#?

I am currently writing a software program for a tour, made up of exhibits. The exhibit object, at any given point, is in one of four states, defined by the ExhibitStates enum:
private enum ExhibitState { Ready, Active, Complete, Inactive };
For developers who will be setting up exhibits, there are only two "starting" states that I want them to be able to choose from:
public enum StartingExhibitState { Ready, Inactive };
Currently, I have it set up so that upon being initialized, the exhibit will immediately set its state to match its starting state, like so:
switch (startingState) {
case StartingExhibitState.Ready:
SetState(ExhibitState.Ready);
break;
case StartingExhibitState.Inactive:
SetState(ExhibitState.Inactive);
break;
}
I found myself wondering today if this was the best practice. Is there a better way to restrict which enum options are public and which are private? Or is it best to simply have the two separate enums?
Thank you so much for your time.
If you create second enum - your intents will be very clearly explained through signature of setting method
public enum ExhibitState
{
Inactive = 0,
Active = 1,
Ready = 2,
Complete = 3
};
public enum InitialStates
{
Inactive = ExhibitState.Inactive,
Ready = ExhibitState.Ready
};
public void SetInitial(InitialStates state)
{
SetState((ExhibitState)state);
}
If you go further you can add compiler help for preventing passing wrong values to the method.
public sealed class InitialState
{
public static readonly InitialState Initial = new InitialState(ExhibitState.Initial);
public static readonly InitialState Ready = new InitialState(ExhibitState.Ready);
public ExhibitState State { get; }
private InitialState(ExhibitState state)
{
State = state;
}
}
Constructor made private to prevent instantiating class from else where.
Class marked as sealed to prevent deriving and changing it behaviour.
Then your method will look like
public void SetInitial(InitialState start)
{
SetState(start.State);
}
// use it
SetInitial(InitialState.Initial);
SetInitial(InitialState.Ready);
Nothing else cannot be passed, until you change code of InitialState class.
Instead of using an enum (or two of them), you could use a class-based approach:
public abstract class ExhibitState
{
public static ExhibitInitialState Ready { get { return new ExhibitReadyState(); } }
public static ExhibitInitialState Inactive { get { return new ExhibitInactiveState(); } }
public static ExhibitState Complete { get { return new ExhibitCompleteState(); } }
public static ExhibitState Active { get { return new ExhibitActiveState(); } }
private class ExhibitReadyState : ExhibitInitialState {}
private class ExhibitInactiveState : ExhibitInitialState {}
private class ExhibitCompleteState : ExhibitState {}
private class ExhibitActiveState : ExhibitState {}
}
public abstract class ExhibitInitialState : ExhibitState {}
The above sample shows a simple approach. Usually, you'd not create a new instance of a state in the get methods, but have static instances so that comparing is easier.
Similar to an enum, you could still type ExhibitState.Ready or the other states. In addition, the base class ExhibitInitialState allows you to limit the states that can be set initially:
public void SetInitial(ExhibitInitialState initState) { ... }
In comparison to the approach that #Fabio proposed, you'd have the benefit that you could not mix up the values. Furthermore and especially relevant for states: is very common that the behavior should also change for a specific state. With this class-based approach, you could implement this behavior in the specific ExhibitState implementations and by that avoid lots of switch statements that are likely to exist in an enum-based approach.

Is this efficient and should I be using encapsulation in a better way?

Here is the code. Please see my questions at the bottom of this post.
public partial class myClass : Other.Class
{
long check1parameter = CurrentSession.CurrentFile.ID;
protected override void EnquiryLoaded(object sender, System.EventArgs e)
{
disableFields();
}
private void disableFields()
{
if (checkEverything()) {
EnquiryForm.GetControl("Status").Enabled = true;
}
}
public bool check1_method(long check1parameter) {
bool Check1 = false;
string stringToCheck = check1parameter.ToString();
if (stringToCheck.Contains("something")) {
Check1 = true;
}
return Check1;
}
public bool checkEverything() {
bool roleCheck = CurrentSession.CurrentUser.IsInRoles("RequiredRole");
bool check1 = check1_method(check1parameter);
bool checkEverything = false;
if (roleCheck && check1) {
checkEverything = true;
}
return checkEverything;
}
//other methods
}
The code is to check that someone has a role and also that a string contains a bit of info and then disable a field. I have simplified this from the actual code to outline the key points. Although the intention is only to run these simple checks and disable a field, I thought it best to create individual methods for these tasks so they can be expanded later on.
I do get an object reference error with long check1parameter being defined in that position. It was in check1_method() and worked correctly but it's something I'd like to be declared once and used across multiple areas if possible.
I also want to pass parameters\variables to check1_method rather than declaring them inside it. What's the best way to approach making check1parameter available to all methods in this partial class? It refers to another class which is linked to Other.Class in some way.
My main question is - how do I make this as efficient as possible and should I be using private in place of public anywhere here? I'm still very new to C# and haven't quite figured out encapsulation yet, so please go easy on me! :)
myClass doesn't need to be declared as partial unless you intend to continue implementing it in a different file.
When using a simple if statement they can be removed, for example you could write:
public partial class myClass : Other.Class
{
long check1parameter = CurrentSession.CurrentFile.ID;
protected override void EnquiryLoaded(object sender, System.EventArgs e)
{
disableFields();
}
private void disableFields()
{
EnquiryForm.GetControl("Status").Enabled = checkEverything();
}
public bool check1_method(long check1parameter) {
return check1parameter.ToString().Contains("something");
}
public bool checkEverything() {
bool roleCheck = CurrentSession.CurrentUser.IsInRoles("RequiredRole");
bool check1 = check1_method(check1parameter);
return (roleCheck && check1);
}
//other methods
}
In order to save yourself from declaring unnecessary bools. Beyond that you'd be sacrificing readability for fewer lines.
When it comes to public vs private, it's good practice to always specify private unless you need to access it from outside of the class. At a glance, disableFields() should probably be public, and check1_method() and checkEverything() be private.
EDIT:
Also, if check1parameter is instantiated globally to myClass, then you don't need to pass it in as a parameter to check1_methods()
The code you provided looks ok. I've made a couple of changes, mostly code aesthetics. The main one is to make the 2 check methods into properties.
public partial class myClass : Other.Class
{
long check1parameter = CurrentSession.CurrentFile.ID;
protected override void EnquiryLoaded(object sender, System.EventArgs e)
{
disableFields();
}
private void disableFields()
{
if (checkEverything)
{
EnquiryForm.GetControl("Status").Enabled = true;
}
}
// the parameter name was the same as a variable in the class
// renamed to avoid confusion
public bool check1_method
{
get {return check1parameter.ToString().Contains("something");}
}
public bool checkEverything
{
get { return CurrentSession.CurrentUser.IsInRoles("RequiredRole")
&& check1_method; }
}
//other methods
}

Control on another form is inaccessible due to it's protection level

TF2SelectDir.txtTF2DirSelect.Text = "";
This is giving me issues, as txtTF2DirSelect is on one form and I'm trying to change it from another. I tried looking it up, and the entire form itself is already public, not private.
Or, to go along with this, how can I create a variable that can be accessed on any form?
Where it goes wrong
if (canFindTF2 == true)
{
TF2SelectDir.txtTF2DirSelect.Text = "";
The form where TF2SelectDir is is already public
public partial class TF2SelectDir : Form
{
public TF2SelectDir()
{
InitializeComponent();
}
Any ideas? Thanks!!
UPDATE
At the bottom of my TF2SelectDir.Designer.cs, I've found
private System.Windows.Forms.TextBox txtTF2DirSelect;
private System.Windows.Forms.Button btnSaveTF2Dir;
private System.Windows.Forms.Label lblExample;
However, when I changed private to public on txtTF2DirSelect, I got a new error.
"An object reference is required for the non-static field, method, or property 'TF2SelectDir.txtTF2DirSelect' - Error Code CS0120
Since I cannot comment, I am posting this as an answer.
Accessing controls from a separate form, may not be the best idea. I would recommend you use properties. Here is Microsoft's definition and usage example of properties.
Another, even better way, in my opinion, to share data between two forms, is to use events. Once again, here is Microsoft's description of events.
If you need a working example of how to use either of these approaches, I would like to see your effort first and then we can build on that.
Expose control in below way .. why?? #monstertjie_za provided few good links on that already .
namespace TF2Overwatch
{
public partial class TF2SelectDir : Form
{
//Approch 1 - usable when the projects most works are done
//without following a good architecture
//You can use a static variable to preserve the state and intilize each time
//a new instance is created
//Approch 2 - Responibilty of preserving text to initlize in textbox should be taken
//by the form who calling this form
//value will pass by consturtor or by exposing property
//all approch 2 code are kept commented for better understanding
private static string strTxtTF2DirSelectTextToInitize;
public TF2SelectDir()
{
InitializeComponent();
txtTF2DirSelect.Text = strTxtTF2DirSelectTextToInitize;
}
public static string TxtTF2DirSelectTextToInitlize
{
get
{
return strTxtTF2DirSelectTextToInitize;
}
set
{
strTxtTF2DirSelectTextToInitize = value;
}
}
//public TF2SelectDir(string txtTF2DirSelectText)
//{
// InitializeComponent();
// txtTF2DirSelect.Text = txtTF2DirSelectText;
//}
//public string TxtTF2DirSelectTextToInitlize
//{
// get
// {
// return txtTF2DirSelect.Text;
// }
// set
// {
// txtTF2DirSelect.Text = value;
// }
//}
}
public partial class SomeAnotherForm:Form
{
public SomeAnotherForm ()
{
InitializeComponent();
}
protected void InSomeAction(object Sender, EventArgs e)
{
if (canFindTF2 == true)
{
TF2SelectDir.TxtTF2DirSelectText = "Test";
TF2SelectDir t1 = new TF2SelectDir();
t1.Show();
//Approch 2
//TF2SelectDir t1 = new TF2SelectDir("Test");
//t1.Show();
//TF2SelectDir t1 = new TF2SelectDir();
//t1.TxtTF2DirSelectText="Test"; //look here TxtTF2DirSelectText is setting on instance not by class
//t1.Show();
}
}
}
}

Change value of control on a form from class (C#)

This should be quite simple really - not sure what the problem is.
I have a C# Class (Public.cs) and a windows form (Form1.cs). Through a function in Public.cs, I want to get the value of a control on Form1 (without having to use object parameters).
// This code appears in Public.cs
public string MyFunction(int num_val)
{
if (chk_num.checked == true)
{
// Something here...
}
}
The issue is that my class cannot find the control on my form. Is there some way that I must reference it in C#?
Thank you.
I would strongly suggest exposing the Checked property via a specific property on Form1 (perhaps with a more meaningful name). This will help to hide the implementation details (i.e. control structure) of the Form1 from it's caller and instead expose only the logic that is required for other consumers to do their job
For example:
public bool IsNumberRequested
{
get { return chk_num.Checked; }
}
Or alternatively, if you still really want to access the control directly, from the designer you can select the control and change it's Modifier property to public (or something else) enabling you to access the control object using the code you originally wrote above.
EDIT: (Response based on comment)
Public.cs will still need a reference to Form1 and then will call the IsNumberRequested property of that object.
// Public.cs
public class Public
{
private Form1 _ui;
public Public(Form1 ui) { _ui = ui };
public string MyFunction(int num_val)
{
if (_ui.IsNumberRequested)
{
// Stuff
}
// Else, default Stuff
}
}
Alternatively, you could pass the form as a parameter to the MyFunction too rather than using it as an instance variable.
I would have the set up the other way around
public class Public
{
public bool CheckNumber {get;set;}
public string MyFunction(int val)
{
if(CheckNumber)
{
//do that thing
}
return ...
}
}
public partial class Form1 : Form
{
Public myinstance = new Public();
public Form1()
{
InitializeComponent();
}
private void CheckBoxChanged(object sender, EventArgs e)
{
myinstance.CheckNumber = chk_num.checked;
}
}
You'll need to assign CheckBoxChanged to the OnChanged event handler for your check box (which I'm assuming is chk_num.
This way your class Public doesn't rely on a form, which it shouldn't.
As Reddog says, use better names, although I half suspect you've just given example names in your question.

Creating a pointer class a bad idea? (C#)

I have a bit of a design dilemma at present. I have an abstract class Firmware which handles file transfer (updating the firmware) and a few other things such as version.
The trouble is that I want to update the file paths of all MyFirmwares in all Devices that I have over the place. One way I can do this is to have a static list of Devices in Device which I iterate over updating Device.FilePath, whenever I set FirmwareFilePath or get an event from Firmware that it's FilePath has changed, remember to clean them up an so on.
** Edit - made this example more complete*
public class Firmware
{
private string _path;
public string Path
{
get { return _path; }
set
{
if (_path == value)
return;
_path = value;
OnPropertyChanged("Path");
}
}
}
public class Device
{
private static readonly List<Device> _Bars = new List<Device>();
private readonly Firmware _myFirmware = new Firmware() ;
public Firmware MyFirmware
{
get { return _myFirmware; }
}
public Device()
{
_Bars.Add(this);
Firmware.PropertyChanged += NewPath;
}
private void NewPath (object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Path")
{
foreach (var dev in _Bars)
dev.MyFirmware.Path = MyFirmware.Path;
}
}
}
Or I could use a "pointer" , change my Getter, Setter and Ctor slightly.
public class Pointer<TField>
{
private TField _backingField;
public TField GetValue()
{
return _backingField;
}
public void SetValue(TField value)
{
_backingField = value;
}
}
public class Firmware
{
private Pointer<string> _pPath;
public string Path
{
get { return _pPath.GetValue(); }
set { _pPath.SetValue(value); }
}
public Firmware (Pointer<String> pPath)
{
_pPath = pPath;
}
}
public class Device
{
private static readonly Pointer<String> _PPath = new Pointer<string>();
public static string Path
{
get { return _PPath.GetValue(); }
set { _PPath.SetValue(value); }
}
private readonly Firmware _myFirmware = new Firmware(_PPath);
public Firmware MyFirmware
{
get { return _myDevice; }
}
}
Is there any agreed upon reason why this would be bad practice? Is there any GC trap I haven't noticed?
Why? As best as I can follow, you want to store an instance of your pointer class on a bunch of objects scattered around all over the place so that they all have a "pointer" to your one main object, and if you update your main object, all the parent classes will be updated, too.
I have several questions:
if Bar has a Foo member, and Foo has a FilePath, why does Bar have a FooFilePath? Any time you need FooFilePath, why not use MyFoo.FilePath? And why is FooFilePath static?
In your second example, instead of each Bar having a MyFoo, it has a pointer - that's the only real thing you've changed. The pointer just has a member that serves the purpose that Foo.FilePath used to serve. So why?
If you just shared an instance of Foo with all instances of Bar, and you changed the value of Foo.FilePath, and made sure that instead of using Bar.FooFilePath all users used Bar.MyFoo.FilePath, then if you change the value of FilePath on that shared Foo instance, every instance of Bar will get the new value automatically anyway, without you having to jump through these hoops.
The problem isn't that your solution won't work, but rather that it's unnecessary.
EDIT: Re: your comment. In that use case, yes, your pointer should work fine, though rather than using a generic pointer class, I'd probably create a class whose entire purpose is to hold shared data - just in case you need more than the file path later on, you already have a container for it. And instead of the double-indirection approach that you're using, you would just use a common reference to this shared instance in all classes that need it.
No, I can't see no GC traps and your solution seems allright although a little odd. What do you need the pointer for? What you're really looking for is a reference, as long as you change the properties of the referenced object all references will be updated too.
If you want to change the object instance itself (which might be the case), I thinks your solution seems about right.

Categories