C# 如何构造从表单控件值获取参数的类对象?
我是C#的新手。我试图使用构造函数实例化一个对象,该对象从表单控件(NumericUpDown和两个复选框)获取参数 通常我在generate Form类中实例化对象,但当我尝试从表单控件传递值时,它会说它无法访问它们 我在InitializeComponent()下有相同的实例化;但这并没有创建对象C# 如何构造从表单控件值获取参数的类对象?,c#,C#,我是C#的新手。我试图使用构造函数实例化一个对象,该对象从表单控件(NumericUpDown和两个复选框)获取参数 通常我在generate Form类中实例化对象,但当我尝试从表单控件传递值时,它会说它无法访问它们 我在InitializeComponent()下有相同的实例化;但这并没有创建对象 namespace DinnerParty { public partial class Form1 : Form { //Usually instantiate he
namespace DinnerParty
{
public partial class Form1 : Form
{
//Usually instantiate here, but in this case my constructor is taking input from the control on the form. I'm getting errors saying it cant
DinnerParty lanparty = new DinnerParty((int)NumberUpDown1.Value, CheckBoxHealth.Checked, CheckBoxDecotations.Checked);
public Form1()
{
InitializeComponent();
//putting the instantiation here doesn't create the object.
DinnerParty lanparty = new DinnerParty((int)NumberUpDown1.Value, CheckBoxHealth.Checked, CheckBoxDecotations.Checked);
DisplayDinnerPartyCost();
}
编辑:我接受了Ryan的建议,但现在它说的是我引用的对象
在DisplayDinnerPartyCost()中,方法为null。以下是更相关的
代码
编辑:这是整个类和表单代码
//class
namespace DinnerParty
{
public class DinnerParty
{
public const int CostOfFoodPerPerson = 25;
public int NumberOfPeople { get; set; }
public bool FancyDecorations { get; set; }
public bool HealthyOption { get; set; }
public decimal Cost { get
{
decimal totalcost = CalculateDecorations(FancyDecorations);
totalcost +=
((CalculateCostOfBeveragesPerPerson(HealthyOption) + CostOfFoodPerPerson) *
NumberOfPeople);
if (HealthyOption)
{
totalcost *= .95M;
return totalcost;
}
else
{
return totalcost;
}
}
}
public DinnerParty(int numberOfPeople, bool healthyOption, bool
fancyDecorations)
{
NumberOfPeople = numberOfPeople;
HealthyOption = healthyOption;
FancyDecorations = fancyDecorations;
}
private decimal CalculateDecorations(bool fancy)
{
decimal CostDeco;
if (FancyDecorations)
{
CostDeco = (NumberOfPeople * 15.00M) + 50M;
return CostDeco;
}
else
{
CostDeco = (NumberOfPeople * 7.50M) + 30M;
return CostDeco;
}
}
private decimal CalculateCostOfBeveragesPerPerson(bool Health)
{
if (HealthyOption)
{
decimal CostOfBeverages = 5.00M;
return CostOfBeverages;
}
else
{
decimal CostOfBeverages = 20.00M;
return CostOfBeverages;
}
}
}
}
//Form code
{
public partial class Form1 : Form
{
DinnerParty lanparty = null;
public Form1()
{
InitializeComponent();
DisplayDinnerPartyCost();
}
private void Form1_Load(object sender, EventArgs e)
{
lanparty = new DinnerParty((int)NumberUpDown1.Value,
CheckBoxHealth.Checked, CheckBoxDecotations.Checked);
DisplayDinnerPartyCost();
}
public void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
lanparty.NumberOfPeople = (int) NumberUpDown1.Value;
DisplayDinnerPartyCost();
}
public void CheckBoxDecotations_CheckedChanged(object sender,
EventArgs e)
{
lanparty.FancyDecorations = CheckBoxDecotations.Checked;
DisplayDinnerPartyCost();
}
public void CheckBoxHealth_CheckedChanged(object sender, EventArgs
e)
{
lanparty.HealthyOption = CheckBoxHealth.Checked;
DisplayDinnerPartyCost();
}
public void DisplayDinnerPartyCost()
{
decimal cost = lanparty.Cost;
labelRetrunCost.Text = cost.ToString("c");
}
}
}
您必须等待直到执行表单加载
namespace DinnerParty
{
public partial class Form1 : Form
{
DinnerParty lanparty = null;
public Form1()
{
InitializeComponent();
}
// Make sure to add event handler for Load
private void Form1_Load(object sender, EventArgs e)
{
lanparty = new DinnerParty((int)NumberUpDown1.Value,
CheckBoxHealth.Checked,
CheckBoxDecotations.Checked);
DisplayDinnerPartyCost();
}
// Make sure that any code that references lanparty does not execute while it is null
public void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
if (lanparty != null)
{
lanparty.NumberOfPeople = (int) NumberUpDown1.Value;
DisplayDinnerPartyCost();
}
}
public void CheckBoxDecotations_CheckedChanged(object sender, EventArgs e)
{
if (lanparty != null)
{
lanparty.FancyDecorations = CheckBoxDecotations.Checked;
DisplayDinnerPartyCost();
}
}
public void CheckBoxHealth_CheckedChanged(object sender, EventArgs e)
{
if (lanparty != null)
{
lanparty.HealthyOption = CheckBoxHealth.Checked;
DisplayDinnerPartyCost();
}
}
// You may need a functions like this, depending on how your code works
private void GetLanPartyConfiguration()
{
if (lanparty != null)
{
lanparty.NumberOfPeople = (int) NumberUpDown1.Value;
lanparty.HealthyOption = CheckBoxHealth.Checked;
lanparty.FancyDecorations = CheckBoxDecotations.Checked;
}
}
private void SetLanPartyControls()
{
if (lanparty != null)
{
NumberUpDown1.Value = lanparty.NumberOfPeople;
CheckBoxHealth.Checked = lanparty.HealthyOption;
CheckBoxDecotations.Checked = lanparty.FancyDecorations;
}
}
public void DisplayDinnerPartyCost()
{
if (lanparty != null)
{
decimal cost = lanparty.Cost;
labelRetrunCost.Text = cost.ToString("c");
}
}
}
}
您的完整代码表明您具有以下功能:
public Form1()
{
InitializeComponent();
DisplayDinnerPartyCost();
}
该代码在Form\u Load
之前执行,因此lanparty
在该阶段仍然是null
如果您这样编写代码:
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
lanparty = new DinnerParty((int)NumberUpDown1.Value, CheckBoxHealth.Checked, CheckBoxDecotations.Checked);
DisplayDinnerPartyCost();
}
…应该很好用
我对你的代码做了一些重构。当费用发生变化时,你应该让
晚餐派对
举办活动。然后,您仅在该事件触发时更新UI。这确保必须填充lanparty
以下是晚餐派对的:
public class DinnerParty
{
private int _numberOfPeople;
private bool _fancyDecorations;
private bool _healthyOption;
public int CostOfFoodPerPerson { get; } = 25;
public int NumberOfPeople
{
get => _numberOfPeople;
set
{
_numberOfPeople = value;
this.CostUpdated?.Invoke(this, new EventArgs());
}
}
public bool FancyDecorations
{
get => _fancyDecorations;
set
{
_fancyDecorations = value;
this.CostUpdated?.Invoke(this, new EventArgs());
}
}
public bool HealthyOption
{
get => _healthyOption;
set
{
_healthyOption = value;
this.CostUpdated?.Invoke(this, new EventArgs());
}
}
public event EventHandler CostUpdated;
public DinnerParty(int numberOfPeople, bool healthyOption, bool fancyDecorations)
{
this._numberOfPeople = numberOfPeople;
this._healthyOption = healthyOption;
this._fancyDecorations = fancyDecorations;
}
public decimal Cost
{
get
{
decimal decorations = CalculateDecorations(_fancyDecorations);
decimal costOfBeveragesPerPerson = CalculateCostOfBeveragesPerPerson(_healthyOption);
decimal costPerPerson = costOfBeveragesPerPerson + this.CostOfFoodPerPerson;
decimal totalcost = costPerPerson * _numberOfPeople + decorations;
if (_healthyOption)
{
totalcost *= .95M;
}
return totalcost;
}
}
private decimal CalculateDecorations(bool fancy)
{
decimal per = _fancyDecorations ? 15m : 7.5m;
decimal flat = _fancyDecorations ? 50m : 30m;
return _numberOfPeople * per + flat;
}
private decimal CalculateCostOfBeveragesPerPerson(bool Health)
=> _healthyOption ? 5m : 20m;
}
这是您的表格1
:
public partial class Form1 : Form
{
DinnerParty lanparty = null;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
lanparty = new DinnerParty((int)NumberUpDown1.Value, CheckBoxHealth.Checked, CheckBoxDecotations.Checked);
lanparty.CostUpdated += lanparty_CostUpdated;
DisplayDinnerPartyCost();
}
private void lanparty_CostUpdated(object sender, EventArgs e)
{
DisplayDinnerPartyCost();
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
lanparty.NumberOfPeople = (int)NumberUpDown1.Value;
}
private void CheckBoxDecotations_CheckedChanged(object sender, EventArgs e)
{
lanparty.FancyDecorations = CheckBoxDecotations.Checked;
}
private void CheckBoxHealth_CheckedChanged(object sender, EventArgs e)
{
lanparty.HealthyOption = CheckBoxHealth.Checked;
}
public void DisplayDinnerPartyCost()
{
decimal cost = lanparty.Cost;
labelRetrunCost.Text = cost.ToString("c");
}
}
只是一个小小的旁注:当有人选择健康的选择时,装饰的成本也会打折扣,这似乎很奇怪。也许有什么需要重新思考?出于某种原因,它仍然会抛出一个错误,表示lanparty为null。这是令人困惑的,因为构造函数应该在窗体上创建一个新对象load@Officer_Narc-如果你需要比Ryan给你的更多的细节,你真的需要发表一篇文章。在这一点上,Ryan看起来是正确的,但是您没有向我们展示的代码中发生了一些事情,因此如果没有进一步的信息,就无法提供帮助。@Officer\u Narc很可能是您在初始化lanparty
之前试图执行代码。您需要等待执行代码,直到lanparty
不为null,或者使用类似以下内容保护访问lanparty的函数:if(lanparty==null){return;}
您需要共享displaydennerpartycost
方法的代码。还要分享哪行代码出错?@Officer\u Narc-这不是一个错误。我需要能够复制、粘贴和编译您的代码。@Officer\u Narc-我们需要看到需要最少编译工作量的完整类。您可以这样做吗?您正在表单加载事件中初始化对象,同时在构造函数的方法调用中使用对象(构造函数代码将在表单加载之前调用,因此您的新错误需要从DisplayDinnerPartyCost();
中删除Form1()
public partial class Form1 : Form
{
DinnerParty lanparty = null;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
lanparty = new DinnerParty((int)NumberUpDown1.Value, CheckBoxHealth.Checked, CheckBoxDecotations.Checked);
lanparty.CostUpdated += lanparty_CostUpdated;
DisplayDinnerPartyCost();
}
private void lanparty_CostUpdated(object sender, EventArgs e)
{
DisplayDinnerPartyCost();
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
lanparty.NumberOfPeople = (int)NumberUpDown1.Value;
}
private void CheckBoxDecotations_CheckedChanged(object sender, EventArgs e)
{
lanparty.FancyDecorations = CheckBoxDecotations.Checked;
}
private void CheckBoxHealth_CheckedChanged(object sender, EventArgs e)
{
lanparty.HealthyOption = CheckBoxHealth.Checked;
}
public void DisplayDinnerPartyCost()
{
decimal cost = lanparty.Cost;
labelRetrunCost.Text = cost.ToString("c");
}
}