C# (wpf) after creating object instance i can not reuse it - c#

I am working on small project, and I am trying to use object to store data. Its only: name, year and price to be stored (max 10 items).
//On click I get user input and I create new object instance
//This is addmovie.xaml.cs
private void btn_add_movie_Click(object sender, RoutedEventArgs e)
{
string m = input_movie_name.Text;
Movie NewMovie = new Movie { Name = m };
}
// This is Movie class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DeNiro
{
public class Movie
{
public string Name {get; set;}
public int year { get; set; }
public string genre { get; set; }
public int price { get; set; }
public List<Movie> Moviez { get; set; }
}
}
PROBLEM:
This is movielist.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace DeNiro
{
/// <summary>
/// Interaction logic for movielist.xaml
/// </summary>
public partial class movielist : Page
{
public movielist()
{
InitializeComponent();
String test = NewMovie.Name;
}
}
}
Why can't I use NewMovie.Name?
Is there a way to create new Movie instance in movielist.xaml.cs and to get previously stored data from it? Please help.

I will try to do it as clear as I can:
The problem is because when you define a variable inside a function without return or without passing it "return" value to another function or to class property or reference, the data is just wasted (this is not the fully programmatically explanation but it will help you understand)
Now in your code, after the button is clicked, a new instance of the class Movie (as you defined it: name, year and price) is created. and that's it, the function finishes, doing nothing with NewMovie.
What you want to do is to pass this instance to a new function:
public partial class movielist: Page
{
// This is list, unlike array you can insert things to it as much as you want
private List<Movie> MoviesList = new List<Movie>();
public movielist()
{
InitializeComponent();
}
public void AddMovie(string newMovie)
{
this.MoviesList.Add(newMovie); // Adds new movie to the movies list
String test = NewMovie.Name;
}
}
And in:
private void btn_add_movie_Click(object sender, RoutedEventArgs e)
{
string m = input_movie_name.Text;
Movie NewMovie = new Movie { Name = m };
this.movielistInstance.AddMovie(NewMovie);
}
And don't forget to set private movielist movielistInstance = new movielist(); in addmovie.xaml.cs class
and for next time, please post the whole addmovie.xaml.cs, it will make us a lot easier to answer.

Related

Passing strings or properties to WPF Code Behind

I can't figure out how to pass any properties or fields or data from my main application into the "Code Behind" of a WPF form.
I'm trying to write an application that lets the user edit some C# parameters from a WPF form following this example:
https://www.tutorialspoint.com/wpf/wpf_data_binding.htm
The example works well enough. The only problem is I don't want to put all of my code in the "Code Behind" class of the form. The program has to do other things, and it will have other forms.
But I can't figure out how to pass any info into the code behind. I even created a public static string in my main application, but even that seems to be out of scope in the Code Behind of the WPF form.
(BTW - I've been dabbling in C# programming for quite a while, but I still don't understand a lot of the more abstract concepts like partial classes and such.)
Thanks for any help.
My main application is a Revit Macro. Here is the main application code with the public static string:
using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
namespace WPF2021Test
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.DB.Macros.AddInId("5973D9EF-F3DA-494B-9992-5636CB0DB94C")]
public partial class ThisApplication
{
///Revit stuff left out
public static string mycomment = "";
public void Tutorial1()
{
UIDocument uidoc = this.ActiveUIDocument;
Document doc = this.ActiveUIDocument.Document;
View pview = uidoc.ActiveView;
Window2 win2 = new Window2 ();
win2.Show();
}
}
}
```
And the code behind I tried:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Linq;
namespace WPF2021Test
{
/// <summary>
/// Interaction logic for Window2.xaml
/// </summary>
public partial class Window2 : Window
{
//The next line doesn't work
Person person = new Person { Name = WPF2021Test.mycomment, Age = 26 };
public Window2()
{
InitializeComponent();
this.DataContext = person;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string message = person.Name + " is " + person.Age;
MessageBox.Show(message);
}
}
public class Person {
private string nameValue;
public string Name {
get { return nameValue; }
set { nameValue = value; }
}
private double ageValue;
public double Age {
get { return ageValue; }
set {
if (value != ageValue) {
ageValue = value;
}
}
}
}
}
Well the problem is, that you have decided to connect your View with the DataContext of "Person".
The question is what are you trying to do?
Why did you connect the DataContext with person and then you will use the code behind? that's doesn't seem to make sense.
Please provide some use case why you even want to connect with the code behind.

How do I create objects and add them to a list with a button click event?

I have a UI which allows the user to create custom objects of class "Bird" by entering name and attributes. I need a button to add the newly created Birds to a "List of Birds". How should my code look like?
The class Bird has a subclass "Nest". Birds can have multiple Nests, hence there's a List of Nests.
I currently have this code, which doesn't work:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Media.Media3D;
using System.Xml.Serialization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace NewBird
{
public partial class MainWindow : Window
{
public MainWindow()
{
}
List<Bird> BirdList = new List<Bird>();
Bird bx = new Bird();
List<Bird.Nest> NList = new List<Bird.Nest>();
private void AddNewBird_Click(object sender, RoutedEventArgs e)
{
Process tempBird = new Process();
string tempName = birdtextbox.Text;
}
private void AddNewNest_Click(object sender, RoutedEventArgs e)
{
Bird.Nest tempNest = new Bird.Nest();
NList.Add(tempNest);
}
private void Add2List_Click(object sender, RoutedEventArgs e)
{
Bird holder = new Bird();
holder= bx;
holder.nl = NList;
BirdList.Add(holder);
}
}
}
public class Bird
{
public string BirdName { get; set; }
public List<Nest> nl { get; set; }
public Nest nest{ get; set; }
[Serializable()]
public class Nest
{
public int Number { get; set; }
}
}
"Add2List_Click" overwrites the previous Bird instead of adding a new one to the BirdList.
Here is what your current code does:
private void Add2List_Click(object sender, RoutedEventArgs e)
{
// Create a new Bird and put it in `holder` variable, so far so good.
Bird holder = new Bird();
// Replace the content of `holder` (our new Bird) with an existing Bird!
// The line `Bird holder = new Bird()` just above became pointless since you never use your new Bird.
// bx is the Bird that was created earlier in your `MainWindow`.
holder= bx;
holder.nl = NList;
// Now you're adding `holder` to the list, but `holder` is not the new Bird anymore, it's the old one.
BirdList.Add(holder);
}
}
What you probably want to do is the following:
private void Add2List_Click(object sender, RoutedEventArgs e)
{
// Create a new Bird and put it in `holder` variable.
Bird holder = new Bird();
// Create a new List with two new Nests for our new Bird...
holder.nl = new List<Bird.Nest> { new Nest(), new Nest() };
// ...or use the existing list of Nests with this line:
// holder.nl = NList;
// Add the new Bird to the list.
BirdList.Add(holder);
}
}

How can I access a class passed to a WPF Window?

I'm passing a class to a WPF Window, and binding properties of the class to fields in the WPF Window. I have that working fine, but I want to edit a property of the class, show the changes in the WPF Window, and then return the class back to the application that called the WPF Window.
Here is the code to display the WPF Window. When I try to access newproduct from the RewriteTitle method I cannot.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Inventory_Controller
{
/// <summary>
/// Interaction logic for TitleWindow.xaml
/// </summary>
public partial class TitleWindow : Window
{
public TitleWindow(Product newproduct)
{
this.DataContext = newproduct; //This didn't help
InitializeComponent();
}
private void RewriteTitle(object sender, TextChangedEventArgs e)
{
// Here I want to access newproduct
}
}
}
The easy way to do it is using the private field. You should create a private readonly field to set the value.
public TitleWindow(Product newproduct)
{
this.DataContext = newproduct;
_product = newproduct;
InitializeComponent();
}
private readonly Product _product;
And then you can find the _product in RewriteTitle
private void RewriteTitle(object sender, TextChangedEventArgs e)
{
// Here I want to access newproduct
// Use _product = xx Or _product.Foo = xx;
}

Can not reference a type through an expression why? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am trying to create 2 forms.
In Form 1 I want to save all new contacts, so I can display them later, and I am adding second button opening Form 2 where I want to create a Contact and after closing the window to save the contact in to the list that is created in Form 1. I am getting error:
Can not reference a type through an expression
on f2.Contacts = this.contacts; and I don't know why.
Form 1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Contacts contacts = new Contacts();
public Form1()
{
InitializeComponent();
}
public class Contacts
{
private List<Contacts> people = new List<Contacts>();
public List<Contacts> People
{
get { return people; }
}
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Contacts = this.contacts;
f2.Show();
}
}
}
Form 2:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
public class Contacts
{
private List<Person> persons = new List<Person>();
public List<Person> Persons
{
get
{
return this.persons;
}
}
}
public Contacts contacts { get; set; }
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Person p = new Person();
p.Name = textBox1.Text;
p.LastName = textBox2.Text;
p.PhoneNumber = textBox3.Text;
p.eMail = textBox4.Text;
this.contacts.Persons.Add(p);
}
public class Person
{
public string Name { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string eMail { get; set; }
}
}
}
You are (accidentally) referring to the nested Contacts class. When you use
f2.Contacts = this.contacts;
you refer to the class Form2.Contacts.
But you want to refer to the Form2.contacts property:
f2.contacts = this.contacts;

How to connect datagrid item to another class

Im new here and a relative beginner with programming in C#. I have a problem with my little programm im trying to put together. it should have three windows (it´s in german but it´s easy to understand). In the first one it should have 4 cars with price, power and model in a datagrid i named DGrid. When you click on the button below the second window pops up and there you can choose what type of insurance you want and if you´re going to pay for it every year, or every half-year,ect... and when you click the button below the third window pops up and there is the Sum you have to pay depending on your car model (which you chose in the first window) and the insurance you picked in the second window. Anyway i did the first 2 windows and it´s working properly but the problem i have is that i don´t know how to connect the car i chose in the first window(class) with the third window (where it makes the calculations).
If i write Autos x= (Autos)DGrid.SelectedItem; in the third window, it says it doesnt recognize DGrid name (which is initialized in the first one).
So the question is: How to get the third window to use the selected item from the first one in order to make the calculations?
Here is the code - first window;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Versicherungsrechner
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
Autos a1 = new Autos("Ferrari", 220, 50000);
Autos a2 = new Autos("Lamborghini", 320, 150000);
Autos a3 = new Autos("Maseratti", 520, 250000);
Autos a4 = new Autos("BMW", 250, 55000);
InitializeComponent();
Autos[] auto = new Autos[] { a1, a2, a3, a4 };
DGrid.ItemsSource = auto;
}
public void OnClick(object sender, RoutedEventArgs e)
{
Details d = new Details();
d.Owner = this;
d.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
d.ShowDialog();
}
}
}
Second Window:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Versicherungsrechner
{
/// <summary>
/// Interaction logic for Details.xaml
/// </summary>
public partial class Details : Window
{
public Details()
{
InitializeComponent();
}
public void AnzeigenClick(object sender, RoutedEventArgs e)
{
Ausgabe a = new Ausgabe();
a.Owner = this;
a.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
a.ShowDialog();
}
}
}
And the third:
namespace Versicherungsrechner
{
/// <summary>
/// Interaction logic for Ausgabe.xaml
/// </summary>
public partial class Ausgabe : Window
{
public Ausgabe()
{
InitializeComponent();
}
}
}
And the Car class:
namespace Versicherungsrechner
{
public class Autos
{
public string modell { get; set; }
public double leistung { get; set; }
public double preis { get; set; }
public Autos(string modell, double leistung, double preis)
{
this.modell = modell;
this.leistung = leistung;
this.preis = preis;
}
}
}
If you change this class...
public partial class Ausgabe : Window
{
public Ausgabe()
{
InitializeComponent();
}
}
...to this...
public partial class Ausgabe : Window
{
public Autos SelectedAuto {get;set}
public Ausgabe()
{
InitializeComponent();
}
}
You can then change this code...
public void AnzeigenClick(object sender, RoutedEventArgs e)
{
Ausgabe a = new Ausgabe();
a.Owner = this;
a.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
a.ShowDialog();
}
...to this...
public void AnzeigenClick(object sender, RoutedEventArgs e)
{
Ausgabe a = new Ausgabe();
a.SelectedAuto = DGrid.SelectedValue as Autos;
a.Owner = this;
a.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
a.Setup(); // to do
a.ShowDialog();
}
And this will let the Aufgabe class have something to work with. You can repeat this process with the other classes.
obligatory best practices note: This was the sort of approach people used up until about 2006/2007 before data binding and Xaml became popular. In this era, the approach is considered risky because it invites operational risk. But for the moment it answers your question and lets you proceed with your project.

Categories