Hello everyone,
I am facing an issue using DataForm. I have an abstract class IBacktestOption and several inherited classes. Let's take only two of them : OptionCall and CallSpread. These classes share 4 arguments with IBacktestOption and have their own arguments.
Here is the IBacktestOption class :
This is OptionCall class :
This is CallSpread class :
In my view I have my DataForm declare like this :
And in my view model I initialize my Collection (I use a ViList, which is a structure almost equivalent to a simple List) with an element of OptionCall type :
When I start my application, everything is fine, I have what I want i.e. my DataForm with my 6 fields : "Strike", "ID", "Gearing", "GlobalCap", "GlobalFloor", "Nom".
In my page, I also have a RadComboBox which enables me to choose which formula I want to use. This combobox is binded to this field in my view model :
When I use the ComboBox to change the formula, a new element is added to the DataForm and here is my issue : this new element only have the fields of IBacktestOption class. And when I use Navigation buttons to go back on my first element (OptionCall), the number of fields of the element have been reduced to 4 ("Gearing", "GlobalCap", "GlobalFloor", "Nom").
I want to know if it is possible to have the fields of the inherited classes instead of the ones of IBacktestOption.
Moreover, in reality I don't need to have a list of IBacktestOption in my DataForm, I only need to have the current option (the one which is selected in the combobox). So, I have tried to empty my List when I change the option type in the combobox :
It works, I have the good number of fields for each option type. But, I need to click on the Next Item Navigation Button to reach my element. Indeed, the first one is empty. It is not really handy for a user. So, I also want to know if there is a way to click on this button automatically.
Finally, I have a last request. As, I don't really need a List for my elements, I tried to use a IBacktestOption instead of a ViList<IBacktestOption> in BactestOpt field. But I didn't manage to have fields printed in DataForm, the DataForm was empty...
Thank you very much for your help.
Regards,
Thomas
I am facing an issue using DataForm. I have an abstract class IBacktestOption and several inherited classes. Let's take only two of them : OptionCall and CallSpread. These classes share 4 arguments with IBacktestOption and have their own arguments.
Here is the IBacktestOption class :
public abstract class IBacktestOption { #region fields private double mGearing; public double Gearing { get { return mGearing; } set { mGearing = value; } } private double? mGlobalCap; public double? GlobalCap { get { return mGlobalCap; } set { mGlobalCap = value; } } private double? mGlobalFloor; public double? GlobalFloor { get { return mGlobalFloor; } set { mGlobalFloor = value; } } public string Nom { get; set; } #endregion protected IBacktestOption(double aGearing, double? aGlobalCap, double? aGlobalFloor) { Gearing = aGearing; GlobalCap = aGlobalCap; GlobalFloor = aGlobalFloor; } public abstract Dictionary<DateTime, IResultatsBacktest> GetOptionResults(IBacktesting backtest); public abstract bool CheckOption(); }This is OptionCall class :
class OptionCall : IBacktestOption, IEditableObject, INotifyPropertyChanged { #region fields private double mStrike; public double Strike { get { return mStrike; } set { mStrike = value; } } OptionCallData backupOptParamData; private int mID; public struct OptionCallData { internal int ID; internal double Strike; internal double? CapGlobal; internal double? FloorGlobal; internal double Gearing; } public int ID { get { return mID; } } #endregion Fields #region constructors public static OptionCall CreateNewOptionCall(double strike, double gearing = 1, double? cap = null, double? floor = null) { return new OptionCall(strike,gearing,cap,floor); } public OptionCall(double strike, double gearing = 1, double? cap = null, double? floor = null) : base(gearing,cap,floor) { Strike = strike; Nom = "Call"; } #endregion public override Dictionary<DateTime, IResultatsBacktest> GetOptionResults(IBacktesting backtest) { /* ... */
} public override bool CheckOption() { return true; } #region Edition public void BeginEdit() { } public void CancelEdit() { mStrike = this.backupOptParamData.Strike; GlobalCap = this.backupOptParamData.CapGlobal; GlobalFloor = this.backupOptParamData.FloorGlobal; Gearing = this.backupOptParamData.Gearing; } public void EndEdit() { this.backupOptParamData.Strike = mStrike; this.backupOptParamData.CapGlobal = GlobalCap; this.backupOptParamData.FloorGlobal = GlobalFloor; this.backupOptParamData.Gearing = Gearing; } #endregion Edition #region Events public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string info) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(info)); } #endregion Events }This is CallSpread class :
class CallSpread : IBacktestOption, IEditableObject, INotifyPropertyChanged { #region fields private double mStrike1; public double Strike1 { get { return mStrike1; } set { mStrike1 = value; } } private double mStrike2; public double Strike2 { get { return mStrike2; } set { mStrike2 = value; } } OptionCallData backupOptParamData; private int mID; public struct OptionCallData { internal int ID; internal double Strike1; internal double Strike2; internal double? CapGlobal; internal double? FloorGlobal; internal double Gearing; } public int ID { get { return mID; } } #endregion Fields #region constructors public static CallSpread CreateNewCallSpread(double strike1, double strike2, double gearing = 1, double? cap = null, double? floor = null) { return new CallSpread(strike1, strike2, gearing, cap, floor); } public CallSpread(double strike1, double strike2, double gearing = 1, double? cap = null, double? floor = null) : base(gearing,cap,floor) { Strike1 = Math.Min(strike1, strike2); Strike2 = Math.Max(strike1, strike2); Nom = "Call Spread"; } #endregion public override Dictionary<DateTime, IResultatsBacktest> GetOptionResults(IBacktesting backtest) { /* ... */ } public override bool CheckOption() { return true; } #region Edition public void BeginEdit() { } public void CancelEdit() { mStrike1 = this.backupOptParamData.Strike1; mStrike2 = this.backupOptParamData.Strike2; GlobalCap = this.backupOptParamData.CapGlobal; GlobalFloor = this.backupOptParamData.FloorGlobal; Gearing = this.backupOptParamData.Gearing; } public void EndEdit() { this.backupOptParamData.Strike1 = mStrike1; this.backupOptParamData.Strike2 = mStrike2; this.backupOptParamData.CapGlobal = GlobalCap; this.backupOptParamData.FloorGlobal = GlobalFloor; this.backupOptParamData.Gearing = Gearing; } #endregion Edition #region Events public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string info) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(info)); } #endregion Events }In my view I have my DataForm declare like this :
<telerik:RadDataForm Grid.Column="1" Margin="12,0,6,21" Grid.ColumnSpan="2" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" ItemsSource="{Binding BacktestOpt}" CommandButtonsVisibility="Cancel,Commit,Edit,Navigation" Grid.Row="1" Height="456" Grid.RowSpan="2" />And in my view model I initialize my Collection (I use a ViList, which is a structure almost equivalent to a simple List) with an element of OptionCall type :
private ViList<IBacktestOption> mBacktestOpt; public ViList<IBacktestOption> BacktestOpt { get { if (mBacktestOpt == null && Formule == 0) { ViList<IBacktestOption> newBacktestOpt = new ViList<IBacktestOption>(); newBacktestOpt.Add(Creators.CreateNewOptionCall(0)); this.mBacktestOpt = new ViList<IBacktestOption>(newBacktestOpt); Formule = PayoffFormule.CALL; } return mBacktestOpt; } set { mBacktestOpt = value; OnPropertyChanged("BacktestOpt"); } }When I start my application, everything is fine, I have what I want i.e. my DataForm with my 6 fields : "Strike", "ID", "Gearing", "GlobalCap", "GlobalFloor", "Nom".
In my page, I also have a RadComboBox which enables me to choose which formula I want to use. This combobox is binded to this field in my view model :
private PayoffFormule mFormule; public PayoffFormule Formule { get { return mFormule; } set { mFormule = value; switch (mFormule) { case PayoffFormule.CALL : Backtest.Option = Creators.CreateNewOptionCall(0); break; case PayoffFormule.PUT : Backtest.Option = Creators.CreateNewOptionPut(0); break; case PayoffFormule.ASIAN_CALL: Backtest.Option = Creators.CreateNewAsianCall(0); break; case PayoffFormule.ASIAN_PUT: Backtest.Option = Creators.CreateNewAsianPut(0); break; case PayoffFormule.CALL_SPREAD: Backtest.Option = Creators.CreateNewCallSpread(0,0.15); break; default: break; } BacktestOpt.Add(Backtest.Option); OnPropertyChanged("BacktestOpt"); OnPropertyChanged("Formule"); } }When I use the ComboBox to change the formula, a new element is added to the DataForm and here is my issue : this new element only have the fields of IBacktestOption class. And when I use Navigation buttons to go back on my first element (OptionCall), the number of fields of the element have been reduced to 4 ("Gearing", "GlobalCap", "GlobalFloor", "Nom").
I want to know if it is possible to have the fields of the inherited classes instead of the ones of IBacktestOption.
Moreover, in reality I don't need to have a list of IBacktestOption in my DataForm, I only need to have the current option (the one which is selected in the combobox). So, I have tried to empty my List when I change the option type in the combobox :
private PayoffFormule mFormule; public PayoffFormule Formule { get { return mFormule; } set { mFormule = value; BacktestOpt.RemoveAt(0); switch (mFormule) { case PayoffFormule.CALL : Backtest.Option = Creators.CreateNewOptionCall(0); break; case PayoffFormule.PUT : Backtest.Option = Creators.CreateNewOptionPut(0); break; case PayoffFormule.ASIAN_CALL: Backtest.Option = Creators.CreateNewAsianCall(0); break; case PayoffFormule.ASIAN_PUT: Backtest.Option = Creators.CreateNewAsianPut(0); break; case PayoffFormule.CALL_SPREAD: Backtest.Option = Creators.CreateNewCallSpread(0,0.15); break; default: break; } BacktestOpt.Add(Backtest.Option); OnPropertyChanged("BacktestOpt"); OnPropertyChanged("Formule"); } }It works, I have the good number of fields for each option type. But, I need to click on the Next Item Navigation Button to reach my element. Indeed, the first one is empty. It is not really handy for a user. So, I also want to know if there is a way to click on this button automatically.
Finally, I have a last request. As, I don't really need a List for my elements, I tried to use a IBacktestOption instead of a ViList<IBacktestOption> in BactestOpt field. But I didn't manage to have fields printed in DataForm, the DataForm was empty...
Thank you very much for your help.
Regards,
Thomas