Passing strings or properties to WPF Code Behind - c#

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.

Related

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;
}

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

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.

Is Main() required in a WPF application? [duplicate]

This question already has answers here:
No Main() in WPF?
(7 answers)
Closed 4 years ago.
I'm totally new to .NET and I'm trying to get to know C# by running the codes I encounter in the books I follow..
I'm building a simple WPF app with a button, which should print out the hypoteneuse.
My question is; In the bellow code example from the book, there is these two namespaces (Syncfusion and NamespaceDemo). Do I have to include them both? What is a better way to use these code? Secondly, When creating a new WPF file and a button for the application, it automatically generates this piece of code:
public MainWindow()
{
InitializeComponent();
}
I know that the MainWindow() is for the design that will include the button. How does it differs from the Main() function in a simple C# console application?
I would appreciate a clear explaination about my confusion with how this different things has to be structured properly. Do I need a Main()?
This is the code from book:
using static System.Math;
namespace Syncfusion
{
public class Calc
{
public static double Pythagorean(double a, double b)
{ double cSquared = Pow(a, 2) + Pow(b, 2);
return Sqrt(cSquared); }
}
}
using Syncfusion;
using System;
using Crypto = System.Security.Cryptography;
namespace NamespaceDemo
{
class Program
{
static void Main()
{
double hypotenuse = Calc.Pythagorean(2, 3);
Console.WriteLine("Hypotenuse: " + hypotenuse);
Crypto.AesManaged aes = new Crypto.AesManaged();
Console.ReadKey();
}
}
}
This is my implementation, which unfortunately doesn't work.
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;
using static System.Math;
namespace Syncfusion
{
public class Calc
{
public static double Pythagorean(double a, double b)
{
double cSquared = Pow(a, 2) + Pow(b, 3);
return Sqrt(cSquared);
}
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
void Button_Click(object sender, RoutedEventArgs e)
{
double hypotenuse = Calc.Pythagorean(2, 4);
MessageBox.Show("Hypotenuse: " + hypotenuse);
}
}
}
All C# programs require a static Main methods as an entry point. MainWindow is a class, not an entry point.

How to use the Debug API in Visual Studio Extension?

I have seen a lot about the related issues, but still feel very puzzled
I now mainly encountered the problem is unable to obtain the current state of the debugging process, such as when to encounter breakpoints.
I have seen a lot of problems that can be used IDebugEventCallback2 to solve the problem, but I was a novice, no specific examples difficult to understand
I have never written this related code, MSDN can be found on the information is also very few examples, if there are some information or examples I would be very grateful....QAQ
English is not my mother tongue, there may be some grammatical mistakes and i feel Sorry for it.
this answer is base on the Visual Studio Package template in C#
File structure is as follows, different project name settings may be different but similar, I have made changes to the selected two documents (MyControl.xaml, VSPackageHW2Package.cs)
FileStruct
1.Define the variable
public static VSPackageHW2Package package;
readonly IVsDebugger _debugger;
readonly DTE _dte;
readonly Debugger2 _dteDebugger;
readonly uint _debuggerEventsCookie;
2.pass value from VSPackageHW2Package.cs to MyControl.xaml(the only place to change VSPackageHW2Package.cs)
public VSPackageHW2Package()
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
MyControl.package = this;
}
3.Implement interface in MyControl.xaml
IVsDebuggerEvents
4.in Constructor
public MyControl()
{
InitializeComponent();
var packageServiceProvider = (IServiceProvider)package;
_debugger = packageServiceProvider.GetService(typeof(SVsShellDebugger)) as IVsDebugger;
_dte = packageServiceProvider.GetService(typeof(SDTE)) as DTE;
if (_debugger.AdviseDebuggerEvents(this, out _debuggerEventsCookie) != VSConstants.S_OK)
{
MessageBox.Show("DebugManager setup failed");
}
else
{
MessageBox.Show("ok");
}
}
Complete MyControl.xaml file:
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
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.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Company.VSPackageHW2
{
/// <summary>
/// Interaction logic for MyControl.xaml
/// </summary>
public partial class MyControl : UserControl,IVsDebuggerEvents
{
public static VSPackageHW2Package package;
readonly IVsDebugger _debugger;
readonly DTE _dte;
readonly Debugger2 _dteDebugger;
readonly uint _debuggerEventsCookie;
public MyControl()
{
InitializeComponent();
var packageServiceProvider = (IServiceProvider)package;
_debugger = packageServiceProvider.GetService(typeof(SVsShellDebugger)) as IVsDebugger;
_dte = packageServiceProvider.GetService(typeof(SDTE)) as DTE;
if (_debugger.AdviseDebuggerEvents(this, out _debuggerEventsCookie) != VSConstants.S_OK)
{
MessageBox.Show("DebugManager setup failed");
}
else
{
MessageBox.Show("ok");
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions")]
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(string.Format(System.Globalization.CultureInfo.CurrentUICulture, "We are inside {0}.button1_Click()", this.ToString()),
"lzyToolWindow");
}
public int OnModeChange(DBGMODE dbgmodeNew)
{
MessageBox.Show("debug mode change");
throw new NotImplementedException();
}
}
}

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