So I have two classes in my project, one where it says
namespace WindowsApplication13
{
partial class Form1
and one where is says:
namespace WindowsApplication13
{
public partial class Form1 : Form
{
public Form1()
{
string text1, text2, text3, text4;
InitializeComponent();
text1 = textBox1.Text;
text2 = textBox2.Text;
text3 = textBox3.Text;
text4 = textBox4.Text;
}
}
}
}
So how do I then instansiate the latter in my Class1?
I have tried
Form1 : Form f1 = new Form1 : Form();
and
Form1 f1 = new Form1();
and
Form f1 = new Form();
But none of them works since when I try to get a variable from the Form1 : Form, I just get the error "WindowsApplication13.Form1" does not contain a definition for "text1".
Sorry if this post is messy or bad done. I can explain more in comments if needed. Thanks!
Edit: Sorry I know the syntax if Form f1 = new Form, I just forgot while writing this!
I assume this is meant to be C#? If so, you'd declare a variable and instantiate the class like this:
Form1 form = new Form1();
The Form1 : Form is part of the class declaration to show that it inherits from Form. You don't need it as part of the variable declaration.
(We can't tell what's wrong with regards to text1 - you haven't told us anything about how it's declared or how you're trying to use it.)
The correct syntax to declare a variable is
Form1 varName = new Form1();
Form1 is the name of your class; the fact that it's partial doesn't make any difference.
If you want to access a control in the form, you'll need to make it public first. (or, better yet, hide it behind a public property that exposes the functionality you need)
Related
So I have this program set up for a simple dialogue tree, where I want to display a question and two options in the unity editor, and if you click one option, you either go to another level of the tree or a leaf. I want to use the composite design pattern to make separate level instances, each with different parameters for one question and two options and add them together into a list. What I'm stuck on is how do I start at the first level and traverse down the tree depending on which button I press. It seems like no matter what I do, it only displays the last level parameters added to the list. The best I can think is maybe add some sort of shifting list function during the button click events. If anyone could shoot some ideas, I would appreciate it. Thank you.
public class Level : MonoBehaviour {
bool button1Pressed;
bool button2Pressed;
private void Start()
{
Level Level1 = new Level("Hello", "Hi", "Shut Up");
Level leaf1 = new Level("Don't be Rude");
Level Level2 = new Level("What you Doing?", "Not Much", "None of your Business");
Level leaf2 = new Level("Well Excuuuuse Me");
Level Level3 = new Level("Can I do that too?", "Sure", "Go Away");
Level leaf3 = new Level("Fine. Be a Jerk");
Level Level4 = new Level("This is boring, can we do something else?", "Why not?", "You're boring");
Level leaf4 = new Level("I'll go be boring somewhere else");
Level Level5 = new Level("You want ice cream?", "Sounds Good", "I'm allergic");
Level leaf5 = new Level("ok.......");
Level leaf = new Level("I Want Chocolate");
Level1.add(Level1);
Level1.add(leaf1);
Level2.add(Level3);
Level2.add(leaf2);
Level3.add(Level4);
Level3.add(leaf3);
Level4.add(Level5);
Level4.add(leaf4);
Level5.add(leaf5);
Level5.add(leaf);
}
public static Text Textbox;
public static Button Button1;
public static Button Button2;
public string OptionA;
public string OptionB;
public string Question;
public string Leaf;
private List<Level> levels;
public Level(string question, string optionA, string optionB)
{
this.Question = question;
this.OptionA = optionA;
this.OptionB = optionB;
GameObject.FindGameObjectWithTag("Level").GetComponentInChildren<Text>().text = Question;
GameObject.FindGameObjectWithTag("OptionA").GetComponentInChildren<Text>().text = OptionA;
GameObject.FindGameObjectWithTag("OptionB").GetComponentInChildren<Text>().text = OptionB;
levels = new List<Level>();
}
public Level(string leaf)
{
this.Leaf = leaf;
Textbox.text = leaf;
}
public void add(Level lvl)
{
levels.Add(lvl);
}
public List<Level> getLevels()
{
return levels;
}
public void Button1Pressed()
{
}
public void Button2Pressed()
{
}
}
public class Initializer : MonoBehaviour {
public Text Textbox;
public Button Button1;
public Button Button2;
void Awake()
{
Level.Textbox = this.Textbox;
Level.Button1 = this.Button1;
Level.Button2 = this.Button2;
}
}
The short answer: All nodes know their parent and children.
There are a few ways to approach this problem. I'll explain an approach using a tree structure with multiple node classes. First we can examine the interactions with the player as you've outlined:
Making a dialog choice (speaking)
Observing a dialog response (listening)
There's also some important conditions we need to consider:
User terminated conversations
AI terminated conversations
From this outline we can build our tree with some classes. I've scratched out some examples but I haven't tested them. Hopefully it conveys the idea and you can build your own solution. It may also be more useful for you to make a single Node class that just knows which type it is. Another improvement would be using an interface or some way to generalize the parent/child relationship which would allow for more complicated tree structures.
class ChoiceNode
{
public ChoiceNode(ResponseNode myParent)
{
parent = myParent;
}
ResponseNode parent = null;
List<ResponseNode> children = new List<ResponseNode>;
bool canSayGoodbye = true;
}
class ResponseNode
{
public ResponseNode(ChoiceNode myParent, string myMessage)
{
parent = myParent;
parent.children.Add(this);
response = myMessage;
}
ChoiceNode parent;
ChoiceNode child;
string response;
}
We should now be able to use a method to display dialog choice by simply enumerating the ResponseNode.children. Then whenever we make a dialog choice we want to display the ResponseNode.response and then move to the ResponseNode.child to find the next set of dialog choices. When parent == null we're at the root branch. When child == null we display some termination text.
I hope this is helpful and gives you some ideas.
Ok, I tried to understand the logic of your code but there are several things that I don't understand, maybe it's better if I try to explain my "Unity dialogue tree".
First:
We need to create a Tree object. If you just want a binary tree you just need tree variables:
public class BinaryTree{
private string root;
private BinaryTree left;
private BinaryTree right
getters/setters
}
this object don't even need to be a Unity component.
root is "dialog"
left is "optionA"
right is "optionB"
if you don't need multiple answer just make left=right.
If you need a way to identify multiple answer I suggest you to create an object like this:
public class Tree{
private Dictionary<string,string> root;
private List<Tree> next;
getters/setters
}
root is again your dialog. A key (that identify your answer) and a value that is the actual dialog.
next is a List of Tree (you identify your answer by making a loop in your next and by checking the key of the dictionary).
Now in the Start method you need to create a new Tree object and set your nexts.
Example
Start(){
BinaryTree bn = new BinaryTree();
bn.Root = "Is this a question?";
BinaryTree left = new BinaryTree();
left.Root = "Nope";
bn.Left = left;
BinaryTree right = new BinaryTree();
right.Root = "Yes it is...";
bn.Right = right;
}
Almost the same for the Tree version:
Start(){
Tree bn = new Tree();
bn.Root = new Dictionary<string, string>();
bn.Root.Add("key1", "Do you need something?");
bn.Next = new List<Tree>();
Tree answer1 = new Tree();
answer1.Root = new Dictionary<string, string>();
answer1.Root.Add("key2", "Yes");
bn.Next.Add();
... iterate...
}
Of course this is just a basic example. The best way to initialize that is to add your dialog to an array and iterate.
Anyway.
Now you can (for example) create a button. In the Start you can Initialize it's text value to your root. In the PointerDown/Clicked method you can make an array of the possible answer keys and, for example, you can decide to generate multiple buttons for multiple answers (or just use 2 static button answer with the BinaryTree) and change the text based on the answer root value (or left/right value). each of the answer button should, in the PointerDown/Clicked method, send the key value (or left/right object) of your user selection (in practice the next value that will display in the main question button).
Of course the "question button" once clicked again should display the next of your answer (and maybe you can decide to add a bool question variable to your object... or maybe you can just decide to use only the left side for a question... or maybe you can decide that if there is only 1 value in the next List that value is a question and it should just show it in the main button text value).
And if the next is null of course you can end the conversation.
There are multiple ways to do this.
When I initialize d3.js and dc.js using JsniBundle there is no global variable "dc" or "d3" that is created. But I initialze crossfilter in the same way and there is window.crossfilter present.
My question is: what is the best way to call methods from the dc library using JsniBundle? Is using JsUtils.prop(window, "dc") the correct way to get a reference to the library object?
In the method drawBarChartWidget() below, the variable "dc" is null.
public interface D3Bundle extends JsniBundle {
#LibrarySource("d3.js")
public void initD3();
}
public interface CrossfilterBundle extends JsniBundle {
#LibrarySource("crossfilter.js")
public abstract void initCrossfilter();
}
public abstract static class DCBundle implements JsniBundle {
#LibrarySource("dc.js")
public abstract void initDC();
public void drawBarChart(Widget container, JSONValue data, Properties chartConfig) {
JavaScriptObject dc = JsUtils.prop(window, "dc");
}
}
LayoutPanel layoutPanel = new LayoutPanel();
SimplePanel chartPanel = new SimplePanel();
public ChartDemo() {
D3Bundle d3 = GWT.create(D3Bundle.class);
CrossfilterBundle crossfilter = GWT.create(CrossfilterBundle.class);
final DCBundle dc = GWT.create(DCBundle.class);
d3.initD3();
crossfilter.initCrossfilter();
dc.initDC();
Maybe not a direct answer to your question, but if you want to use d3.js with GWT, there is a wrapper that cover most of the main APIs from d3.js :
https://github.com/gwtd3/gwt-d3
Here's what made it work:
change final assignment statement in d3.js library from
this.d3 = d3;
to
window.d3 = d3;
and change final assignment statement in dc.js library from
this.dc = _dc(d3);
to
window.dc = _dc(window.d3);
I assume this is because of some weirdness around the iframe context that GWT code is executed in, but I'm not totally clear on why it works. I haven't done it yet but I believe that instead of editing the original library you can use the "replace" attribute of the LibrarySource annotation to automate that substitution.
I have a viewmodel and it exists out of entity framework classes (just plain classes). I Read on stackoverflow that it's okey to put an inotifypropertychanged in the model. So I did that in order not to have a lot of extra code.
So, now I have to perform an action when a property changes in one of my list items... the thing is, I can't react on this, in my viewmodel...
What do I do?
I have come across this issue once I started making larger projects with the MVVM pattern.
In the end I just shifted my INotifyPropertyChanged event calls to the ViewModel properties. I also decorated these properties with validation notification as that is where most of the validation that needs a user to react to will be held, any common elements can also be pulled out to a base ViewModel where relevant.
Another issue that you might come across as time goes by is where to put some of your processing logic. I used to have mine at the Model level, but then some of them required a bit closer interaction with the UI (validation reasons mainly), but if I put it in the ViewModel then I would have to have references to my repositories etc. In the end my ViewModels have access to another layer (a Service Layer) where this takes place. (A prime example for the use of this would be if you have a column in a database which is unique that you need to check when a user has created/modified data belonging to this column.)
Anyway, that is just a bit of extra information that I had to figure out shortly after the issue your currently having!
i fought with the best stategy for this for a while. I found that there are a number of different ways to do this.
First thing to note, if you add the property validation/notification directly to your model classes then the notifictaion and validation will happen when the class is created and for each object that gets created in observable collections, which in turn can cause performance issues or other challenges. So for that reason I moved my validation and notification into a "helper" partial class for the model.
So the model gets created through the Entity framework, lets say for an object called Job. I create public partial class called job as well. Here is an example (in vb, I can convert to C# if you need)
Partial Public Class job
Inherits ValidationBase
#Region "CONSTRUCTORS"
Public Sub New()
''default values
Me.FTC_Type = 4
Me.dtCreated = Now
Me.dtUpdated = Now
HasChanges = False
End Sub
Public Sub New(bValidate As Boolean)
PropertyValitaion(bValidate)
''default values
Me.FTC_Type = 4
Me.dtCreated = Now
Me.dtUpdated = Now
HasChanges = False
End Sub
Public ReadOnly Property DisplayPath
Get
Return "W" + idJob.ToString + ": " + chrTitle + " - " + client.chrCompany
End Get
End Property
Public ReadOnly Property SearchPath
Get
Return "W" + idJob.ToString + " " + chrTitle + " " + client.chrCompany + " " + chrContact
End Get
End Property
#End Region
#Region "VALIDATION FUNCTIONS"
Public Overrides Function Validate(validationContext As ComponentModel.DataAnnotations.ValidationContext) As IEnumerable(Of ComponentModel.DataAnnotations.ValidationResult)
Return MyBase.Validate(validationContext)
PropertyValitaion(True)
End Function
Public Sub PropertyValitaion(bAllProperties As Boolean, Optional sProperty As String = "")
'initialize validation helper
If bAllProperties OrElse sProperty = "chrTitle" Then
If String.IsNullOrEmpty(chrTitle) Then
AddError("chrTitle", "You must enter a Job Title")
Else
RemoveError("chrTitle")
End If
End If
End Sub
#End Region
End Class
So you can see that I can create other readonly properties (Like display title etc) and create my own custom validation that gets called when I want. THis validation uses the IDataErrorInfo for getting tied back into the UI. I have two constructors, one the calls the property validation and one that does not. That way I can control when it happens.
I created a ValidationBase class that my Objects partial class inhertis from. THis saves me from having to manually implement IdataErrorInfo and INotifyPropertyCHnaged in every partial class for every object.
Here is my validation base:
Imports System.ComponentModel
Imports System.Collections.Concurrent
Imports System.ComponentModel.DataAnnotations
Imports System.ComponentModel.DataAnnotations.Schema
Public Class ValidationBase
Implements IValidatableObject, IDataErrorInfo, INotifyPropertyChanged
#Region "DECLARATIONS"
Protected _propertyErrors As New Dictionary(Of String, String)
Protected _validationResults As New List(Of ValidationResult)
Public ReadOnly Property HasErrors() As Boolean
Get
Return (_propertyErrors.Count + _validationResults.Count) > 0
End Get
End Property
#End Region
#Region "IValidatableObject IMPLEMENTATION"
Public Overridable Function Validate(validationContext As ValidationContext) As IEnumerable(Of ValidationResult) Implements IValidatableObject.Validate
Return Nothing
End Function
#End Region
#Region "iDataError OBJECTS"
'Returns an error message
'In this case it is a general message, which is
'returned if the list contains elements of errors
Public ReadOnly Property [Error] As String Implements System.ComponentModel.IDataErrorInfo.Error
Get
If _propertyErrors.Count > 0 Then
Return "Object data is invalid"
Else
Return Nothing
End If
End Get
End Property
Default Public ReadOnly Property Item(ByVal columnName As String) As String Implements System.ComponentModel.IDataErrorInfo.Item
Get
If _propertyErrors.ContainsKey(columnName) Then
Return _propertyErrors(columnName).ToString
Else
Return Nothing
End If
End Get
End Property
#End Region
#Region "IDataError FUNCTIONS"
'Adds an error to the collection, if not already present
'with the same key
Protected Sub AddError(ByVal columnName As String, ByVal msg As String)
If Not _propertyErrors.ContainsKey(columnName) Then
_propertyErrors.Add(columnName, msg)
OnPropertyChanged(columnName)
End If
End Sub
'Removes an error from the collection, if present
Protected Sub RemoveError(ByVal columnName As String)
If _propertyErrors.ContainsKey(columnName) Then
_propertyErrors.Remove(columnName)
OnPropertyChanged(columnName)
End If
End Sub
Public Sub ClearErrors()
_propertyErrors.Clear()
End Sub
#End Region
#Region "INotifyPropertyChanged IMPLEMENTATION"
Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
Public Overridable Sub OnPropertyChanged(ByVal propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
#End Region
End Class
SO i can't say this is the totally right way because there does not seem to be a clear best pratcie defined out there. But this works for me and I hope it can help you.
I am trying to call to class from form2 in C# for, example below is code from "Form2".
private void button17_Click(object sender, EventArgs e)
{
Form1 frontmain = new Form1();
frontmain.buttonchange();
this.Hide();
}
This will not excute the class in "Form1" called "buttonchange." Below is the code for the "buttonchange" class:
public void buttonchange()
{
button1.Text = workshop1;
button2.Text = workshop2;
button3.Text = workshop3;
button4.Text = workshop4;
button5.Text = workshop5;
{
I assume it has something to do with privacy settings between form1 and form2 however I have never found the solution. I have always worked around it somehow. Does anyone know what the issue is here?
I would set up events on form2 and set up form1 to capture the form1 events.
Here is a link to setting up events:
http://msdn.microsoft.com/en-us/library/awbftdfh.aspx
You're creating a new instance of Form1 and calling code upon that, which is probably not what you actually intend to do.
If you're trying to refer to an existing instance of Form1, then you'll need to refer to that (rather than create a new instance).
If an instance of Form1 spawns the form that your click handler is in, you can refer to it like this:
Form1 frontmain = this.Owner as Form1;
If an instance of Form1 doesn't spawn your second form with the click handler, then you will need to take an event-based approach (which is a better approach anyway, as it eliminates dependencies).
I am using SmartGWT 2.4, and I have two types of TabSet(s), each one has a different look and feel, and I am facing a problem implementing that.
The new TabSet has been implemented as the following :
public class MainTabSet extends TabSet{
public MainTabSet(){
super.setStylePrimaryName("MainTabSet");
build();
}
private void build(){
setMargin(6);
setWidth100();
setHeight100();
setStyleName("nt-main-tabset");
Tab inboxTab = new Tab("Inbox");
inboxTab.setPane(new InboxPane().get());
}
}
based on the last paragraph (Multiple looks for the same component type) here :
I've defined a new class that holds the same primary name I used above :
isc.defineClass("MainTabSet", "TabSet");
and then I've added some properties to it :
isc.MainTabSet.addProperties({
tabBarThickness:100,
scrollerButtonSize:100,
pickerButtonSize:100,
symmetricScroller:false,
symmetricPickerButton:false,
scrollerSrc:"nothing",
pickerButtonSrc:"nothingg",
closeTabIconSize:100
})
The code above has been written at the top of section 6 (TabSet) in load_skin.js file.
Now, I am still getting the same old TabSet look and feel in MainTabSet.
my Questions now are :
did I follow the right steps to achieve my goal ?
how could I consider new classes to some sub elements of TabSet -like TabBar- but only for the new component (MainTabSet)?
Thank you guys.
According to last paragraph of the article that you have mentioned, you were suppose to call setScClassName("MainTabSet") to apply smartClient's js class to your java class. I think that should be something like this:
public class MainTabSet extends TabSet{
public MainTabSet(){
setScClassName("MainTabSet");
build();
}
private void build(){
setMargin(6);
setWidth100();
setHeight100();
setStyleName("nt-main-tabset");
Tab inboxTab = new Tab("Inbox");
inboxTab.setPane(new InboxPane().get());
}
}