I am currently working on a BMI calculator for my C# class. My app asks the user for either their height in feet and inches and their weight in pounds or their height in centimeters and weight in kilograms. Their is a tab control that has buttons for Imperial mode or Metric mode.
If the "calculate" button in the imperial tab is clicked, I need to make sure that the heightFt, heightIn, and weightLbs text boxes have been filled out. Then I convert those to the metric units. If the calculate button in the metric tab is clicked, I need to make sure that the heightCm and weightKg text boxes have been filled out.
Once those are provided, I then convert the height and weight to BMI. If I use if(heightFt == null) I get the following error:
The result of the expression is always 'false' since a value of type 'double' is never equal to 'null' of type 'double?'
How do I fix this?
This is my MainWindow.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 BMICalculator
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private BMICalc _BMICalc;
public MainWindow()
{
_BMICalc = new BMICalc();
InitializeComponent();
}
private void calculateImperial_Click(object sender, RoutedEventArgs e)
{
_BMICalc.heightFt = Convert.ToDouble(heightFt.Text);
_BMICalc.heightIn = Convert.ToDouble(heightIn.Text);
_BMICalc.weightLbs = Convert.ToDouble(weightLbs.Text);
_BMICalc.doCalculation("Imperial");
if (_BMICalc.error == null)
{
MessageBox.Show("Your BMI is " + _BMICalc.bmi + " and you are " + _BMICalc.category, "Your BMI");
}
}
}
}
This is BMICalc.cs
using System;
using System.Windows;
using System.ComponentModel;
namespace BMICalculator
{
class BMICalc :INotifyPropertyChanged
{
public double _heightFt { get; set; }
public double _heightIn { get; set; }
public double _heightCm { get; set; }
public double _weightLbs { get; set; }
public double _weightKg { get; set; }
public double _bmi { get; set; }
public string _category { get; set; }
public string _error { get; set; }
public double heightFt
{
get { return heightFt; }
set
{
_heightFt = value;
OnPropertyChanged("heightFt");
}
}
public double heightIn
{
get { return _heightIn; }
set
{
_heightIn = value;
OnPropertyChanged("heightIn");
}
}
public double heightCm
{
get { return _heightCm; }
set
{
_heightCm = value;
OnPropertyChanged("heightCm");
}
}
public double weightLbs
{
get { return _weightLbs; }
set
{
_weightLbs = value;
OnPropertyChanged("weightLbs");
}
}
public double weightKg
{
get { return _weightKg; }
set
{
_weightKg = value;
OnPropertyChanged("weightKg");
}
}
public double bmi
{
get { return _bmi; }
set
{
_bmi = value;
OnPropertyChanged("bmi");
}
}
public string error
{
get { return _error; }
set
{
_error = value;
OnPropertyChanged("error");
}
}
public string category
{
get { return _category; }
set
{
_category = value;
OnPropertyChanged("category");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName){
if(PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public void doCalculation(string calculationMode){
if(calculationMode == "Imperial"){
if (heightFt == null)
{
this.error = "You must provide a value for your height in feet!";
}
else if (heightIn == null)
{
this.error = "You must provide a value for your height in inches!";
}
else if (weightLbs == null)
{
this.error = "You must provide a value for your weight in pounds!";
}
else
{
heightFt = Convert.ToDouble(heightFt);
heightIn = Convert.ToDouble(heightIn);
weightLbs = Convert.ToDouble(weightLbs);
_weightKg = Convert.ToDouble(_weightLbs * (1 / 2.2));
_heightCm = Convert.ToDouble((_heightFt + (_heightIn / 12) / 0.032808));
}
} else if(calculationMode == "Metric"){
this.bmi = weightKg / Math.Pow((heightCm / 100), 2);
if (this.bmi < 18.5)
{
this.category = "underweight";
}
else if (this.bmi >= 18.5 && this.bmi < 24.9)
{
this.category = "normalweight";
}
else if (this.bmi >= 25 && this.bmi <= 29.9)
{
this.category = "overweight";
}
else if (this.bmi > 30)
{
this.category = "obese";
}
}
}
}
}
}
You can make you double properties to be nullable so you can compare to null (the default).
Example:
public double? heightIn
{
get { return _heightIn; }
set {
_heightIn = value;
OnPropertyChanged("heightIn");
}
}
In this case, make sure you change the type of the corresponding private variables to match.
You never set a default value for your properties. As double cannot be null you'll probably want to check against 0 instead. The properties you begin with underscores should just be private variables with default values. Also consider using metric only internally.
class BMICalc :INotifyPropertyChanged
{
private double _heightFt = 0;
private double _heightIn = 0;
private double _heightCm = 0;
private double _weightLbs = 0;
private double _weightKg = 0;
private double _bmi = 0;
private string _category = null;
private string _error = null;
public double heightFt
{
get { return _heightFt; }
set
{
_heightFt = value;
OnPropertyChanged("heightFt");
}
}
public double heightIn
{
get { return _heightIn; }
set
{
_heightIn = value;
OnPropertyChanged("heightIn");
}
}
public double heightCm
{
get { return _heightCm; }
set
{
_heightCm = value;
OnPropertyChanged("heightCm");
}
}
public double weightLbs
{
get { return _weightLbs; }
set
{
_weightLbs = value;
OnPropertyChanged("weightLbs");
}
}
public double weightKg
{
get { return _weightKg; }
set
{
_weightKg = value;
OnPropertyChanged("weightKg");
}
}
public double bmi
{
get { return _bmi; }
set
{
_bmi = value;
OnPropertyChanged("bmi");
}
}
public string error
{
get { return _error; }
set
{
_error = value;
OnPropertyChanged("error");
}
}
public string category
{
get { return _category; }
set
{
_category = value;
OnPropertyChanged("category");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName){
if(PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public void doCalculation(string calculationMode){
if(calculationMode == "Imperial"){
if (heightFt == null)
{
this.error = "You must provide a value for your height in feet!";
}
else if (heightIn == null)
{
this.error = "You must provide a value for your height in inches!";
}
else if (weightLbs == null)
{
this.error = "You must provide a value for your weight in pounds!";
}
else
{
heightFt = Convert.ToDouble(heightFt);
heightIn = Convert.ToDouble(heightIn);
weightLbs = Convert.ToDouble(weightLbs);
_weightKg = Convert.ToDouble(_weightLbs * (1 / 2.2));
_heightCm = Convert.ToDouble((_heightFt + (_heightIn / 12) / 0.032808));
}
} else if(calculationMode == "Metric"){
this.bmi = weightKg / Math.Pow((heightCm / 100), 2);
if (this.bmi < 18.5)
{
this.category = "underweight";
}
else if (this.bmi >= 18.5 && this.bmi < 24.9)
{
this.category = "normalweight";
}
else if (this.bmi >= 25 && this.bmi <= 29.9)
{
this.category = "overweight";
}
else if (this.bmi > 30)
{
this.category = "obese";
}
}
}
}
}
Related
The float word I think is inappropriate but...
I try to make a custom slider control and seems to work fine but for some reason for some values the control crashes.
For example if I choose Maximum value = 1.112 the slider show maximum 1.111 and if I increase the value with numeric Up Down I get this error:
System Argument Out Of Range Exception H Result = 0x80131502
Message=Value of '1112' is not valid for 'Value'. 'Value' should be
between 'Minimum' and 'Maximum'.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace UserSliderControl
{
//set the default event for this user control
[DefaultEvent("ValueChanged")]
public partial class SliderControl : UserControl
{
//set the initial values
private int multiplier = 1;
private float minimum = 0f;
private float maximum = 100f;
private int decimalPlaces = 0;
private float _value = 0f;
private float resetvalue = 0f;
private int largeChange = 5;
private Image buttonResetImage = null;
private Color controlNameForeColor = SystemColors.WindowText;
//set the event handler for this user control = ValueChanged
public event EventHandler ValueChanged;
//set the properties for this user control
#region properties
public string ControlName
{
get { return labelControlName.Text; }
set
{
labelControlName.Text = value;
}
}
public Color ControlNameForeColor
{
get { return controlNameForeColor; }
set
{
controlNameForeColor = value;
labelControlName.ForeColor = controlNameForeColor;
}
}
public Image ButtonResetImage
{
get { return buttonResetImage; }
set
{
buttonResetImage = value;
btnReset.BackgroundImage = buttonResetImage;
btnReset.BackgroundImageLayout = ImageLayout.Zoom;
}
}
public float Value
{
get { return _value; }
set
{
_value = value;
if (_value > maximum) _value = maximum;
if (_value < minimum) _value = minimum;
NumericUpDown.Value = (decimal)_value;
}
}
public float ResetValue
{
get { return resetvalue; }
set
{
resetvalue = value;
if (resetvalue > maximum) resetvalue = maximum / 2;
if (resetvalue < minimum) resetvalue = minimum;
}
}
public float Maximum
{
get { return maximum; }
set
{
maximum = value;
if (maximum < minimum)
{
maximum = 2 * minimum;
}
TrackBar.Maximum = (int)(maximum * multiplier);
NumericUpDown.Maximum = (decimal)maximum;
}
}
public float Minimum
{
get { return minimum; }
set
{
minimum = value;
if (minimum > maximum)
{
minimum = 0;
}
TrackBar.Minimum = (int)minimum * multiplier;
NumericUpDown.Minimum = (int)minimum;
}
}
public int DecimalPlaces
{
get { return decimalPlaces; }
set
{
decimalPlaces = value;
if (decimalPlaces > 3)
{
decimalPlaces = 3;
}
multiplier = (int)Math.Pow(10, decimalPlaces);
NumericUpDown.DecimalPlaces = decimalPlaces;
NumericUpDown.Increment = 1m / multiplier;
}
}
public int LargeChange
{
get { return largeChange; }
set
{
largeChange = value;
TrackBar.LargeChange = largeChange;
}
}
#endregion
public SliderControl()
{
InitializeComponent();
}
private void TrackBar_Scroll(object sender, EventArgs e)
{
NumericUpDown.Value = (decimal)TrackBar.Value / multiplier;
Value = (float)TrackBar.Value / multiplier;
OnValueChanged();
}
private void NumericUpDown_ValueChanged(object sender, EventArgs e)
{
TrackBar.Value = (int)(NumericUpDown.Value * multiplier);
Value = (float)NumericUpDown.Value;
OnValueChanged();
}
private void btnReset_Click(object sender, EventArgs e)
{
NumericUpDown.Value = (decimal)ResetValue;
TrackBar.Focus();
OnValueChanged();
}
protected virtual void OnValueChanged()
{
ValueChanged?.Invoke(this, EventArgs.Empty);
}
}
}
I have a simple app that stores different stock data, my add stock button opens a new window with a form and when I press save I add the stock to the database but the datagrid doesn't get updated
I access the static instance of my main Viewmodel from my EntryViewModel via:
Main View Model(StockViewModel)
public class StockViewModel:INotifyPropertyChanged
{
#region Fields
private IList<Stock> _stockList;
private StatsBuilder _statsBuilder = new StatsBuilder();
public Stock stock = new Stock();
public Stock10 stock10 = new Stock10();
public Stock20 stock20 = new Stock20();
private ICommand _searchCommand;
private static StockViewModel _instance = new StockViewModel();
public static StockViewModel Instance { get { return _instance; } }
public IList<Stock> Stocks
{
get { return _stockList; }
set { _stockList = value; OnPropertyChanged(nameof(Stocks)); }
}
#endregion
#region Constructor
public StockViewModel()
{
using (var stocks = new AppDbContext())
{
Stocks = stocks.LowFloatStocks.ToList();
}
}
#endregion
#region Day1's
private string _ticker;
public string Ticker
{
get { return _ticker; }
set
{
_ticker = value;
OnPropertyChanged("Ticker");
}
}
private DateTime _date = DateTime.Now;
public DateTime Date
{
get { return _date; }
set { _date = value; }
}
private decimal _preivousClose;
public decimal PreviousClose
{
get { return _preivousClose; }
set { _preivousClose = value; OnPropertyChanged("PreviousClose"); }
}
private decimal _pmOpeningPrice;
public decimal PM_OpeningPrice
{
get { return _pmOpeningPrice; }
set { _pmOpeningPrice = value; OnPropertyChanged("PM_OpeningPrice"); }
}
private decimal _openingPrice;
public decimal OpeningPrice
{
get { return _openingPrice; }
set { _openingPrice = value; OnPropertyChanged("OpeningPrice"); }
}
private decimal _high;
public decimal High
{
get { return _high ; }
set { _high = value; OnPropertyChanged("High"); }
}
private decimal _low;
public decimal Low
{
get { return _low; }
set { _low = value; OnPropertyChanged("Low"); }
}
private decimal _close;
public decimal Close
{
get { return _close; }
set { _close = value; OnPropertyChanged("Close"); }
}
private string _catalyst;
public string Catalyst
{
get { return _catalyst; }
set { _catalyst = value; OnPropertyChanged("Catalyst"); }
}
private decimal _float;
public decimal Float
{
get { return _float; }
set {_float = value; OnPropertyChanged("Float"); }
}
private string _dilution;
public string Dilution
{
get { return _dilution; }
set { _dilution = value; OnPropertyChanged("Dilution"); }
}
#endregion
#region Day2's
//public decimal Day2Open
//{
// //get { return stock.Day2Open; }
// set { stock.Day2Open = value; OnPropertyChanged("Day2Open"); }
//}
//public decimal Day2High
//{
// get { return stock.Day2High; }
// set { stock.Day2High = value; OnPropertyChanged("Day2High"); }
//}
//public decimal Day2Low
//{
// get { return stock.Day2Low; }
// set { stock.Day2Low = value; OnPropertyChanged("Day2Low"); }
//}
//public decimal Day2Close
//{
// get { return stock.Day2Close; }
// set { stock.Day2Close = value; OnPropertyChanged("Day2Close"); }
//}
#endregion
#region Stats
private Stock _selectedstock;
public Stock SelectedStock
{
private get
{
return _selectedstock;
}
set
{
_selectedstock = value;
OnPropertyChanged("SelectedStock");
GetStats(_selectedstock.Ticker);
}
}
public int Gaps10 { get { return stock10.Gaps10; } set { stock10.Gaps10 = value; OnPropertyChanged("Gaps10"); } }
public decimal AvgGap10 { get {return stock10.AvgGap10; } set { stock10.AvgGap10 = value; OnPropertyChanged("AvgGap10"); } }
public int CloseGreen10 { get { return stock10.CloseGreen10; } set { stock10.CloseGreen10 = value; OnPropertyChanged("CloseGreen10"); } }
public decimal CloseGreenPercent10 { get { return stock10.CloseGreenPercent10; } set { stock10.CloseGreenPercent10 = value; OnPropertyChanged("CloseGreenPercent10"); } }
public int CloseRed10 { get { return stock10.CloseRed10; } set { stock10.CloseRed10 = value; OnPropertyChanged("CloseRed10"); } }
public decimal CloseRedPercent10 { get { return stock10.CloseRedPercent10; } set { stock10.CloseRedPercent10 = value; OnPropertyChanged("CloseRedPercent10"); } }
public decimal AvgSpike10 { get; set; }
public decimal Downside10 { get; set; }
public int PMFade10 { get { return stock10.PMFade10; } set { stock10.PMFade10 = value; OnPropertyChanged("PMFade10"); } }
public decimal PMFadePercent10 { get { return stock10.PMFadePercent10; } set { stock10.PMFadePercent10 = value; OnPropertyChanged("PMFadePercent10"); } }
public int Gaps20 { get {return stock20.Gaps20 ; } set { stock20.Gaps20 = value; OnPropertyChanged("Gaps20"); } }
public decimal AvgGap20 { get { return stock20.AvgGap20; } set { stock20.AvgGap20 = value; OnPropertyChanged("AvgGap20"); } }
public int CloseGreen20 { get { return stock20.CloseGreen20; } set { stock20.CloseGreen20 = value; OnPropertyChanged("CloseGreen20"); } }
public decimal CloseGreenPercent20 { get { return stock20.CloseGreenPercent20; } set { stock20.CloseGreenPercent20 = value; OnPropertyChanged("CloseGreenPercent20"); } }
public int CloseRed20 { get { return stock20.CloseRed20; } set { stock20.CloseRed20 = value; OnPropertyChanged("CloseRed20"); } }
public decimal CloseRedPercent20 { get { return stock20.CloseRedPercent20; } set { stock20.CloseRedPercent20 = value; OnPropertyChanged("CloseRedPercent20"); } }
public decimal AvgSpike20 { get; set; }
public decimal Downside20 { get; set; }
public int PMFade20 { get { return stock20.PMFade20; } set { stock20.PMFade20 = value; OnPropertyChanged("PMFade20"); } }
public decimal PMFadePercent20 { get { return stock20.PMFadePercent20; } set { stock20.PMFadePercent20 = value; OnPropertyChanged("PMFadePercent20"); } }
#endregion
#region PropertyChange
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region Commands
public ICommand SearchCommand => _searchCommand ?? (_searchCommand = new RelayCommand(param => this.SearchStock(param)));
#endregion
#region Actions
private void SearchStock(object _ticker)
{
try
{
var stock = Stocks.First(x => x.Ticker.Trim() == _ticker.ToString());
_selectedstock = (Stock)stock;
GetStats(_ticker.ToString());
}
catch (Exception)
{
MessageBox.Show("No matching Ticker");
}
}
private void GetStats(string ticker)
{
//Stocks with 10% gap ups
stock10 = _statsBuilder.GetStats10(ticker);
stock20 = _statsBuilder.GetStats20(ticker);
Gaps10 = stock10.Gaps10;
AvgGap10 = stock10.AvgGap10;
CloseGreen10 = stock10.CloseGreen10;
CloseGreenPercent10 = stock10.CloseGreenPercent10;
CloseRed10 = stock10.CloseRed10;
CloseRedPercent10 = stock10.CloseRedPercent10;
PMFade10 = stock10.PMFade10;
PMFadePercent10 = stock10.PMFadePercent10;
//Stock with 20% gap ups
Gaps20 = stock20.Gaps20;
AvgGap20 = stock20.AvgGap20;
CloseGreen20 = stock20.CloseGreen20;
CloseGreenPercent20 = stock20.CloseGreenPercent20;
CloseRed20 = stock20.CloseRed20;
CloseRedPercent20 = stock20.CloseRedPercent20;
PMFade20 = stock20.PMFade20;
PMFadePercent20 = stock20.PMFadePercent20;
}
#endregion
}
When I click the add stock button it fires the AddCommand which in turn fires the Addstock method, this adds the stock to the database and updates the list in the StockViewModel instance but it does not update the datagrid OnPropertyChanged for some reason
EntryViewModel:
public ICommand AddCommand => _addCommand ?? (_addCommand = new RelayCommand(param => this.AddStock()));
#endregion
#region PropertyChange
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region Methods
private void AddStock()
{
using (var stocks = new AppDbContext())
{
stock.Id = 0;
stock.Ticker = _ticker;
stock.PreviousClose = _preivousClose;
stock.PM_OpeningPrice = _pmOpeningPrice;
stock.OpeningPrice = _openingPrice;
stock.High = _high;
stock.Low = _low;
stock.Close = _close;
stock.Catalyst = _catalyst;
stock.Float = _float;
stock.Dilution = _dilution;
stocks.LowFloatStocks.Add(stock);
stocks.SaveChanges();
StockViewModel.Instance.Stocks = stocks.LowFloatStocks.ToList();
Clear();
}
}
Data Grid Binding;
<DataGrid Name="StockGrid" Margin="5,5,5,5" Height="250" ItemsSource="{Binding Stocks}" IsReadOnly="True" AutoGeneratingColumn ="StockGrid_AutoGeneratingColumn" Grid.ColumnSpan="3" VerticalScrollBarVisibility="Auto" SelectedItem="{Binding SelectedStock, Mode=TwoWay}">
</DataGrid>
Data Context of StockView Model:
<Window.DataContext> <local1:StockViewModel/> </Window.DataContext>
Any suggestions?
The following sets the DataContext to an new instance of the StockViewModel which is not the same as the instance returned by the Instance property:
<Window.DataContext> <local1:StockViewModel/> </Window.DataContext>
The fact that you can do this means that StockViewModel is not really a singleton. You should add a private constuctor to it to make it a real singleton if this is what you want:
private StockViewModel() { }
You would then set the DataContext to the instance returned by the Instance property:
<Window.DataContext>
<x:Static Member="this:StockViewModel.Instance" />
</Window.DataContext>
I learn programming oriented object, and I want to do this code but I got those problems, I think I don't really know the concept of virtual.
View image 1
Code:
class Joueur
{
private string _nom;
private string _prenom;
private DateTime _dateDeNaissance;
private string _position;
private bool _reserve;
public string nom
{
get { return _nom; }
set { _nom = value; }
}
public string prenom
{
get { return _prenom; }
set { _prenom = value; }
}
public DateTime dateDeNaissance
{
get { return _dateDeNaissance; }
set { _dateDeNaissance = value; }
}
public string position
{
get { return _position; }
set { _position = value; }
}
public bool reserve
{
get { return _reserve; }
set { _reserve = value; }
}
public Joueur()
{
}
public Joueur(string nom, string prenom, DateTime dateDeNaissance, string position, bool reserve)
{
this.nom = nom;
this.prenom = prenom;
this.dateDeNaissance = dateDeNaissance;
this.position = position;
this.reserve = reserve;
}
public double virtual CalculerPrime(int joues, int gagnes)
{
double Prime;
if (reserve == false)
Prime = 10000 * (gagnes / joues);
else
Prime = ((10000 * (gagnes / joues)) / 2);
return Prime;
}
}
You need to do like this in your code:
public virtual double CalculerPrime(int joues, int gagnes)
{
double Prime;
if (reserve == false)
Prime = 10000 * (gagnes / joues);
else
Prime = ((10000 * (gagnes / joues)) / 2);
return Prime;
}
I have this functional query where I only used fictive tables names for security concerns :
SELECT
h.CENID,
h.BMHFMC,
h.BMHDONEMIDASSTEP1,
h.BMHDONEMIDASSTEP2,
h.LMIID,
h.BMHHOLD,
h.BMHBATCHMIDAS,
h.BMHFMCVALUEDATE AS HeaderValueDate,
h.SUNID,
h.BRAID,
d.BMHID,
d.BMDRUBRIQUE,
d.BMDCLIENT,
d.BMDSEQUENCE,
d.BMDDATE,
d.BMDDEVISE,
d.BMDMONTANT,
d.BMDTYPE,
d.BMDNOTE,
d.BMDENTRYNBRE,
v.DEVDECIMAL ,
NVL(t.TYPVERIFCOMPTEMIDAS, 0) AS TYPVERIFCOMPTEMIDAS
FROM dbo.TableOne h
INNER JOIN dbo.Tabletwoo d
ON h.BMHID = d.BMHID
INNER JOIN dbo.tableThree v
ON d.BMDDEVISE = v.DEVID
LEFT JOIN dbo.TableFour t
ON t.TYPID=h.BMHFMC
WHERE d.BMDMONTANT != 0
AND h.BMHDONEMIDASSTEP1 = 0
AND h.BMHDONEMIDASSTEP2 = 0
AND h.LMIID = 0
AND h.BMHHOLD = 0
And I made a class in order to bind every fields
public class Batch :BaseRepository ,IList<Batch>
{
public Batch()
{
}
private string cendid;
private string bmhfmc;
private double bmhdonemidasstep1;
private double bmhdonemidasstep2;
private double lmiid;
private double bmhhold;
private double bmhbatchmidas;
private DateTime headervaluedateordinal;
private double sunid; //
private string bradid; //
private double bmhid;
private string bmdrubirique; //
private string bmdclient;
private string bmdsequence;
private DateTime bmddate;
private string bmddevise;
private double bmdmontant;
private string bmdtype;
private string bmdnote;
private string bmdentrynbre; //
private double devdecimalordinal;
private double typverifcomptemidasordinal;
public Batch(string cendid, string bmhfmc, double bmhdonemidasstep1, double bmhdonemidasstep2, double lmiid, double bmhhold, double bmhbatchmidas, DateTime headervaluedateordinal, double sunid, string bradid, double bmhid, string bmdrubirique, string bmdclient, string bmdsequence, DateTime bmddate, string bmddevise, double bmdmontant, string bmdtype, string bmdnote, string bmdentrynbre, double devdecimalordinal, double typverifcomptemidasordinal)
{
this.cendid = cendid;
this.bmhfmc = bmhfmc;
this.bmhdonemidasstep1 = bmhdonemidasstep1;
this.bmhdonemidasstep2 = bmhdonemidasstep2;
this.lmiid = lmiid;
this.bmhhold = bmhhold;
this.bmhbatchmidas = bmhbatchmidas;
this.headervaluedateordinal = headervaluedateordinal;
this.sunid = sunid;
this.bradid = bradid;
this.bmhid = bmhid;
this.bmdrubirique = bmdrubirique;
this.bmdclient = bmdclient;
this.bmdsequence = bmdsequence;
this.bmddate = bmddate;
this.bmddevise = bmddevise;
this.bmdmontant = bmdmontant;
this.bmdtype = bmdtype;
this.bmdnote = bmdnote;
this.bmdentrynbre = bmdentrynbre;
this.devdecimalordinal = devdecimalordinal;
this.typverifcomptemidasordinal = typverifcomptemidasordinal;
}
public string Cendid
{
get { return cendid; }
set { cendid = value; }
}
public string Bmhfmc
{
get { return bmhfmc; }
set { bmhfmc = value; }
}
public double Bmhdonemidasstep1
{
get { return bmhdonemidasstep1; }
set { bmhdonemidasstep1 = value; }
}
public double Bmhdonemidasstep2
{
get { return bmhdonemidasstep2; }
set { bmhdonemidasstep2 = value; }
}
public double Lmiid
{
get { return lmiid; }
set { lmiid = value; }
}
public double Bmhhold
{
get { return bmhhold; }
set { bmhhold = value; }
}
public double Bmhbatchmidas
{
get { return bmhbatchmidas; }
set { bmhbatchmidas = value; }
}
public DateTime Headervaluedateordinal
{
get { return headervaluedateordinal; }
set { headervaluedateordinal = value; }
}
public double Sunid
{
get { return sunid; }
set { sunid = value; }
}
public string Bradid
{
get { return bradid; }
set { bradid = value; }
}
public double Bmhid
{
get { return bmhid; }
set { bmhid = value; }
}
public string Bmdrubirique
{
get { return bmdrubirique; }
set { bmdrubirique = value; }
}
public string Bmdclient
{
get { return bmdclient; }
set { bmdclient = value; }
}
public string Bmdsequence
{
get { return bmdsequence; }
set { bmdsequence = value; }
}
public DateTime Bmddate
{
get { return bmddate; }
set { bmddate = value; }
}
public string Bmddevise
{
get { return bmddevise; }
set { bmddevise = value; }
}
public double Bmdmontant
{
get { return bmdmontant; }
set { bmdmontant = value; }
}
public string Bmdtype
{
get { return bmdtype; }
set { bmdtype = value; }
}
public string Bmdnote
{
get { return bmdnote; }
set { bmdnote = value; }
}
public string Bmdentrynbre
{
get { return bmdentrynbre; }
set { bmdentrynbre = value; }
}
public double Devdecimalordinal
{
get { return devdecimalordinal; }
set { devdecimalordinal = value; }
}
public double Typverifcomptemidasordinal
{
get { return typverifcomptemidasordinal; }
set { typverifcomptemidasordinal = value; }
}
Now when I execute the query into a list using dapper
Connection conn = new Connection();
OracleConnection connection = conn.GetDBConnection();
myList= connection.Query<Batch>(querySql).ToList();
Now,while debugging, all fields returns the expected values .But, I noticed those fields below are null in myList not empty but really null , but the problem is they aren't null in the database
Bmdrubirique , Sunid, Bmdentrynbre, Bradid ,Cenid
In oracle database those fields are like the following :
CENID is VARCHAR2(3 BYTE)`
Bmhid is VARCHAR2(3 BYTE)
Sunid is NUMBER(38,0)
Bradid is VARCHAR2(3 BYTE)
I don't get it , where did it go wrong? why other fields are properly loaded while those returns null value ?
My default assumption would be that there is a typo in the real code and the constructor is assigning a value from a field to itself. However, frankly: since you have a public Batch() {} constructor, I'm not sure what the benefit of the second one is - it just adds risk of errors. Likewise with the fields and manual properties.
So if this as me, where you currently have (simplified to two properties):
public class Batch
{
private string cendid;
private string bmhfmc;
public Batch() {}
public Batch(string cendid, string bmhfmc)
{
this.cendid = cendid;
this.bmhfmc = bmhfmc;
}
public string Cendid
{
get { return cendid; }
set { cendid = value; }
}
public string Bmhfmc
{
get { return bmhfmc; }
set { bmhfmc = value; }
}
}
I would have literally just:
public class Batch
{
public string Cendid {get;set;}
public string Bmhfmc {get;set;}
}
All of the rest of the code is just opportunities to make coding errors.
Now: the reason that Cendid is null is because: the column is CENID - only one d. This means that dapper isn't even using your custom constructor, because it isn't a perfect match between the constructor and the columns. Ditto the other fields like BRAID vs BRADID.
So the next thing to do is to fix the typos.
IDataErrorInfo: Validating when page submitted
Here I am using IdataErrorInfo
Below is My MainwindowViewModel Class COde
using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using MahApps.Metro;
using MetroDemo.Models;
using System.Windows.Input;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
namespace MetroDemo
{
public class AccentColorMenuData
{
public string Name { get; set; }
public Brush BorderColorBrush { get; set; }
public Brush ColorBrush { get; set; }
private ICommand changeAccentCommand;
public ICommand ChangeAccentCommand
{
get { return this.changeAccentCommand ?? (changeAccentCommand = new SimpleCommand { CanExecuteDelegate = x => true, ExecuteDelegate = x => this.DoChangeTheme(x) }); }
}
protected virtual void DoChangeTheme(object sender)
{
var theme = ThemeManager.DetectAppStyle(Application.Current);
var accent = ThemeManager.GetAccent(this.Name);
ThemeManager.ChangeAppStyle(Application.Current, accent, theme.Item1);
}
}
public class AppThemeMenuData : AccentColorMenuData
{
protected override void DoChangeTheme(object sender)
{
var theme = ThemeManager.DetectAppStyle(Application.Current);
var appTheme = ThemeManager.GetAppTheme(this.Name);
ThemeManager.ChangeAppStyle(Application.Current, theme.Item2, appTheme);
}
}
public class MainWindowViewModel : INotifyPropertyChanged, IDataErrorInfo
{
private readonly IDialogCoordinator _dialogCoordinator;
int? _integerGreater10Property;
int? _emptystring;
private bool _animateOnPositionChange = true;
public MainWindowViewModel(IDialogCoordinator dialogCoordinator)
{
_dialogCoordinator = dialogCoordinator;
SampleData.Seed();
// create accent color menu items for the demo
this.AccentColors = ThemeManager.Accents
.Select(a => new AccentColorMenuData() { Name = a.Name, ColorBrush = a.Resources["AccentColorBrush"] as Brush })
.ToList();
// create metro theme color menu items for the demo
this.AppThemes = ThemeManager.AppThemes
.Select(a => new AppThemeMenuData() { Name = a.Name, BorderColorBrush = a.Resources["BlackColorBrush"] as Brush, ColorBrush = a.Resources["WhiteColorBrush"] as Brush })
.ToList();
Albums = SampleData.Albums;
Artists = SampleData.Artists;
FlipViewTemplateSelector = new RandomDataTemplateSelector();
FrameworkElementFactory spFactory = new FrameworkElementFactory(typeof(Image));
spFactory.SetBinding(Image.SourceProperty, new System.Windows.Data.Binding("."));
spFactory.SetValue(Image.HorizontalAlignmentProperty, HorizontalAlignment.Stretch);
spFactory.SetValue(Image.StretchProperty, Stretch.Fill);
FlipViewTemplateSelector.TemplateOne = new DataTemplate()
{
VisualTree = spFactory
};
FlipViewImages = new string[] { "http://trinities.org/blog/wp-content/uploads/red-ball.jpg", "http://savingwithsisters.files.wordpress.com/2012/05/ball.gif" };
RaisePropertyChanged("FlipViewTemplateSelector");
BrushResources = FindBrushResources();
CultureInfos = CultureInfo.GetCultures(CultureTypes.InstalledWin32Cultures).ToList();
}
public string Title { get; set; }
public int SelectedIndex { get; set; }
public List<Album> Albums { get; set; }
public List<Artist> Artists { get; set; }
public List<AccentColorMenuData> AccentColors { get; set; }
public List<AppThemeMenuData> AppThemes { get; set; }
public List<CultureInfo> CultureInfos { get; set; }
public int? IntegerGreater10Property
{
get { return this._integerGreater10Property; }
set
{
if (Equals(value, _integerGreater10Property))
{
return;
}
_integerGreater10Property = value;
RaisePropertyChanged("IntegerGreater10Property");
}
}
public string FirstName { get; set; }
public string LastName { get; set; }
DateTime? _datePickerDate;
public DateTime? DatePickerDate
{
get { return this._datePickerDate; }
set
{
if (Equals(value, _datePickerDate))
{
return;
}
_datePickerDate = value;
RaisePropertyChanged("DatePickerDate");
}
}
bool _magicToggleButtonIsChecked = true;
public bool MagicToggleButtonIsChecked
{
get { return this._magicToggleButtonIsChecked; }
set
{
if (Equals(value, _magicToggleButtonIsChecked))
{
return;
}
_magicToggleButtonIsChecked = value;
RaisePropertyChanged("MagicToggleButtonIsChecked");
}
}
private bool _quitConfirmationEnabled;
public bool QuitConfirmationEnabled
{
get { return _quitConfirmationEnabled; }
set
{
if (value.Equals(_quitConfirmationEnabled)) return;
_quitConfirmationEnabled = value;
RaisePropertyChanged("QuitConfirmationEnabled");
}
}
}
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event if needed.
/// </summary>
/// <param name="propertyName">The name of the property that changed.</param>
protected virtual void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public string this[string columnName]
{
get
{
if (columnName == "IntegerGreater10Property" && this.IntegerGreater10Property < 10)
{
return "Number is not greater than 10!";
}
if (columnName == "DatePickerDate" && this.DatePickerDate == null)
{
return "No Date given!";
}
if (columnName == "FirstName")
{
if (string.IsNullOrEmpty(FirstName) || FirstName.Length < 3)
return "Please Enter First Name";
}
if (columnName == "LastName")
{
if (string.IsNullOrEmpty(FirstName) || FirstName.Length < 3)
return "Please Enter Last Name";
}
return null;
}
}
public string Error { get { return string.Empty; } }
private ICommand singleCloseTabCommand;
public ICommand SingleCloseTabCommand
{
get
{
return this.singleCloseTabCommand ?? (this.singleCloseTabCommand = new SimpleCommand
{
CanExecuteDelegate = x => true,
ExecuteDelegate = async x =>
{
await ((MetroWindow) Application.Current.MainWindow).ShowMessageAsync("Closing tab!", string.Format("You are now closing the '{0}' tab", x));
}
});
}
}
private ICommand neverCloseTabCommand;
public ICommand NeverCloseTabCommand
{
get { return this.neverCloseTabCommand ?? (this.neverCloseTabCommand = new SimpleCommand { CanExecuteDelegate = x => false }); }
}
private ICommand showInputDialogCommand;
public ICommand ShowInputDialogCommand
{
get
{
return this.showInputDialogCommand ?? (this.showInputDialogCommand = new SimpleCommand
{
CanExecuteDelegate = x => true,
ExecuteDelegate = x =>
{
_dialogCoordinator.ShowInputAsync(this, "From a VM", "This dialog was shown from a VM, without knowledge of Window").ContinueWith(t => Console.WriteLine(t.Result));
}
});
}
}
private ICommand showProgressDialogCommand;
public ICommand ShowProgressDialogCommand
{
get
{
return this.showProgressDialogCommand ?? (this.showProgressDialogCommand = new SimpleCommand
{
CanExecuteDelegate = x => true,
ExecuteDelegate = x => RunProgressFromVm()
});
}
}
}
}
Below is My XAml Code
<TextBox Name="txt_LA_FirstName"
Controls:TextBoxHelper.Watermark="First Name"
Controls:TextBoxHelper.UseFloatingWatermark="True"
ToolTip="First Name" Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" Text="{Binding FirstName, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True}" />
Event Is Raising at form load and showing Error Messages Before user enters any Value> I need to show Error Messages After Button Click Event
The reason why you get it is because the content of your indexer is static, so the View validates it during the binding. You should only validate it when the property changes though.
You should have a backing field for an errors dictionary with Add/Remove methods, like this
private readonly Dictionary<string, string> errors = new Dictionary<string, string>();
public string this[string columnName]
{
get
{
string errorMessage = null;
if (errors.TryGetValue(columnName, errorMessage)
{
return errorMessage;
}
return null;
}
}
protected void AddErrorMessage(string columnName, string errorMessage)
{
errors[columnName] = errorMessage;
}
protected void RemoveErrorMessage(string columnName)
{
if(errors.ContainsKey(columnName))
{
errors.Remove(columnName);
}
}
protected virtual void Validate()
{
errors.Clear();
if (this.IntegerGreater10Property < 10)
{
this.AddErrorMessage("IntegerGreater10Property", "Number is not greater than 10!");
}
if (this.DatePickerDate == null)
{
this.AddErrorMessage("DatePickerDate", "No Date given!");
}
if (string.IsNullOrEmpty(FirstName) || FirstName.Length < 3)
{
this.AddErrorMessage("FirstName", "Please Enter First Name");
}
if (string.IsNullOrEmpty(LastName) || Lastname.Length < 3)
{
this.AddErrorMessage("LastName", "Please Enter Last Name");
}
}
And then remove them with RemoveMessage("FirstName") or clear it up on validation. You should implement this in a base class of course, to avoid repeating this code over and over again and just override the Validate() method in your ViewModel classes
Thanks for your reply
Even I tried it I had solved it By creating on Bool variable and declaring it as False in MainwindowView model class.
Unless and Until the Bool Variable is True it wont Validates
On Button click Event I will Enable the bool Variable to True then It starts Validates on Button CLick
if (Enable)
{
if (columnName == "IntegerGreater10Property" && this.IntegerGreater10Property < 10)
{
return "Number is not greater than 10!";
}
if (columnName == "DatePickerDate" && this.DatePickerDate == null)
{
return "No Date given!";
}
if (columnName == "FirstName")
{
if (string.IsNullOrEmpty(FirstName) || FirstName.Length < 3)
return "Please Enter First Name";
}
if (columnName == "LastName")
{
if (string.IsNullOrEmpty(FirstName) || FirstName.Length < 3)
return "Please Enter Last Name";
}
}
return null;
Below is My Button click Event (On Button I will Enable the Bool Property to true
var x = (MainWindowViewModel)DataContext;
x.Enable = true;
var binding = txt_LA_FirstName.GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();