using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using DevExpress.Customization; using DevExpress.Data; using DevExpress.Skins; using DevExpress.Sparkline; using DevExpress.StockMarketTrader.Model.BusinessObjects; using DevExpress.StockMarketTrader.ViewModel; using DevExpress.Utils; using DevExpress.Utils.About; using DevExpress.XtraBars; using DevExpress.XtraBars.Docking; using DevExpress.XtraCharts; using DevExpress.XtraEditors; using DevExpress.XtraEditors.Repository; using DevExpress.XtraGrid; using DevExpress.XtraGrid.Columns; using DevExpress.XtraGrid.Views.Base; using DevExpress.XtraGrid.Views.Grid.ViewInfo; namespace DevExpress.StockMarketTrader { public partial class StockWorkspacesUC : XtraUserControl { int selectedPiePointIndex = 0; string selectedCompanyName; Color red = Color.Red; Color green = Color.Green; public StockWorkspacesUC() { InitializeComponent(); UpdateCustomColors(); } void UpdateCustomColors() { red = CommonColors.GetCriticalColor(DevExpress.LookAndFeel.UserLookAndFeel.Default); green = CommonColors.GetInformationColor(DevExpress.LookAndFeel.UserLookAndFeel.Default); } void StockWorkspacesUC_Load(object sender, EventArgs e) { if(StockMarketView.defaultViewModel == null) return; StockMarketView.defaultViewModel.CurrentPriceIndexChanged += defaultViewModel_CurrentPriceIndexChanged; StockMarketView.defaultViewModel.PropertyChanged += defaultViewModel_PropertyChanged; //watchList watchListGridView.OptionsBehavior.AutoPopulateColumns = false; watchListGridView.OptionsBehavior.CacheValuesOnRowUpdating = CacheRowValuesMode.Disabled; watchListGrid.MainView.DataController.AllowIEnumerableDetails = false; watchListGridView.FocusRectStyle = XtraGrid.Views.Grid.DrawFocusRectStyle.None; watchListGrid.DataSource = StockMarketView.defaultViewModel.WatchListBindingData; GridColumn col = watchListGridView.Columns.Add(); col.FieldName = "CompanyName"; col.Caption = "Symbol"; col.Visible = true; col = watchListGridView.Columns.Add(); col.FieldName = "Price"; col.Caption = "Last Price"; //col.ColumnEdit = new ArrowButtonRepositoryItem(); col.DisplayFormat.FormatType = FormatType.Numeric; col.DisplayFormat.FormatString = "c"; col.Visible = true; col = watchListGridView.Columns.Add(); col.FieldName = "Volume"; col.DisplayFormat.FormatType = FormatType.Numeric; col.DisplayFormat.FormatString = "n0"; col.Visible = true; col = watchListGridView.Columns.Add(); col.FieldName = "Volume Dynamics"; RepositoryItemSparklineEdit rise = new RepositoryItemSparklineEdit(); col.ColumnEdit = rise; col.UnboundType = Data.UnboundColumnType.Object; AreaSparklineView view = new AreaSparklineView(); view.HighlightMaxPoint = true; view.HighlightMinPoint = true; rise.View = view; col.Visible = true; col = watchListGridView.Columns.Add(); col.FieldName = "Rise"; col.Name = "Rise"; col.Visible = false; //col = watchListGridView.Columns.Add(); //col.FieldName = "TotalRise"; //col.Name = "TotalRise"; //col.Visible = false; //FormatConditionRuleIconSet val = new FormatConditionIconSetPositiveNegativeTriangles() { RangeDescription = "0, >0" }; //watchListGridView.FormatRules.Add(new GridFormatRule() { Rule = val, Column = watchListGridView.Columns["Rise"], ColumnApplyTo=watchListGridView.Columns[1]}); var rule = watchListGridView.FormatRules.AddIconSetRule(watchListGridView.Columns["Rise"], new FormatConditionIconSetPositiveNegativeTriangles() { RangeDescription = "<0, 0, >0" }); rule.ColumnApplyTo = watchListGridView.Columns[1]; rule.Enabled = true; watchListGridView.BestFitColumns(); watchListGridView.FocusedRowChanged += new XtraGrid.Views.Base.FocusedRowChangedEventHandler(watchListGridView_FocusedRowChanged); //watchListGridView.CustomDrawCell += watchListGridView_CustomDrawCell; watchListGridView.CustomUnboundColumnData += watchListGridView_CustomUnboundColumnData; //chart stockChartUC.stockChart.Series["Price"].DataSource = StockMarketView.defaultViewModel.StockChartBindingData; stockChartUC.stockChart.Series["Price"].ArgumentDataMember = "Date"; stockChartUC.stockChart.Series["Price"].ValueDataMembers.AddRange(new string[] { "Low", "High", "Open", "Close" }); stockChartUC.stockChart.Series["Volume"].DataSource = StockMarketView.defaultViewModel.StockChartBindingData; stockChartUC.stockChart.Series["Volume"].ArgumentDataMember = "Date"; stockChartUC.stockChart.Series["Volume"].ValueDataMembers.AddRange(new string[] { "Volume" }); //volumeChart volumeChart.Series[0].DataSource = StockMarketView.defaultViewModel.VolumeChartBindingData; volumeChart.Series[0].ArgumentDataMember = "CompanyName"; volumeChart.Series[0].ToolTipPointPattern = "Argument: {A} Value: {V}"; volumeChart.Series[0].ValueDataMembers.AddRange(new string[] { "Volume" }); //transationsGrid transactionGridView.OptionsBehavior.AutoPopulateColumns = false; transactionGrid.DataSource = StockMarketView.defaultViewModel.TransactionGridBindingData; var fceAsk = new FormatConditionRuleExpression() { Expression = "Ask > 0", PredefinedName = "Red Fill" }; transactionGridView.FormatRules.AddRule(new GridFormatRule() { ApplyToRow = true, Rule = fceAsk }); var fceBid = new FormatConditionRuleExpression() { Expression = "Bid > 0", PredefinedName = "Green Fill" }; transactionGridView.FormatRules.AddRule(new GridFormatRule() { ApplyToRow = true, Rule = fceBid }); StockMarketView.defaultViewModel.WatchListChanged += defaultViewModel_WatchListChanged; helpBarItemButton.ImageOptions.SvgImage = SvgResources.GetSvgImage("Help"); bbiSwatches.ImageOptions.SvgImage = SvgResources.GetSvgImage("Swatches"); bsiConnectedStatus.ImageOptions.SvgImage = SvgResources.GetSvgImage("Connected"); } void defaultViewModel_WatchListChanged(object sender, EventArgs e) { watchListGridView.RefreshData(); } void UpdateNetworkState() { bsiConnectedStatus.Caption = StockMarketView.defaultViewModel.NetworkState; } void defaultViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e) { if(e.PropertyName == "NetworkState" && FindForm() != null) { this.FindForm().BeginInvoke(new MethodInvoker(UpdateNetworkState), new object[] { }); } } void OnVolumeChartBoundDataChanged(object sender, EventArgs e) { if(volumeChart.Series[0].Points.Count > 0 && selectedPiePointIndex != -1 && volumeChart.Series[0].Points.Count > selectedPiePointIndex) { DoughnutSeriesView view = volumeChart.Series[0].View as DoughnutSeriesView; for(int i = 0; i < volumeChart.Series[0].Points.Count; i++) { if(selectedCompanyName == volumeChart.Series[0].Points[i].Argument.ToString()) { ExplodePoint(volumeChart.Series[0].Points[i], view); selectedPiePointIndex = i; break; } } } } //void watchListGridView_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e) { // if(StockMarketView.defaultViewModel == null) // return; // GridCellInfo info = e.Cell as GridCellInfo; // if(info == null) // return; // CompanyTradingDataViewModel rowData = watchListGridView.GetRow(e.RowHandle) as CompanyTradingDataViewModel; // ArrowButtonRepositoryItem arrowb = info.Editor as ArrowButtonRepositoryItem; // if(info.Column.FieldName == "Price" && arrowb != null) { // arrowb.ContextImageOptions.SvgImage = SvgResources.GetSvgImage(rowData.Rise == 0 ? "Up" : "Down"); // info.ViewInfo.DetailLevel = XtraEditors.Controls.DetailLevel.Full; // info.ViewInfo.CalcViewInfo(); // } //} void defaultViewModel_CurrentPriceIndexChanged(object sender, EventArgs e) { if(StockMarketView.defaultViewModel == null) return; transactionGridView.FocusedRowHandle = StockMarketView.defaultViewModel.CurrentPriceIndex; } void watchListGridView_FocusedRowChanged(object sender, FocusedRowChangedEventArgs e) { StockMarketView.defaultViewModel.SelectedCompany = watchListGridView.GetFocusedRow() as CompanyTradingDataViewModel; selectedCompanyName = StockMarketView.defaultViewModel.SelectedCompany.CompanyName; SeriesPoint sPoint = FindSeriesPointByName(StockMarketView.defaultViewModel.SelectedCompany.CompanyName); DoughnutSeriesView view = volumeChart.Series[0].View as DoughnutSeriesView; if(sPoint != null && view != null) ExplodePoint(sPoint, view); else view.ExplodedPoints.Clear(); } //void transactionGridView_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e) { // if(StockMarketView.defaultViewModel == null) // return; // double cellValue = -1; // GridCellInfo info = e.Cell as GridCellInfo; // if(info == null) // return; // double.TryParse(e.CellValue.ToString(), out cellValue); // if(cellValue != -1) { // if(cellValue == 0) { // info.Appearance.ForeColor = e.Appearance.BackColor; // return; // } // TransactionData rowData = transactionGridView.GetRow(e.RowHandle) as TransactionData; // if(rowData.TransactionType == "Ask") // info.Appearance.ForeColor = green; // else info.Appearance.ForeColor = red; // } //} void volumeChart_MouseDown(object sender, MouseEventArgs e) { SeriesPoint seriesPoint = volumeChart.CalcHitInfo(e.Location).SeriesPoint; DoughnutSeriesView view = volumeChart.Series[0].View as DoughnutSeriesView; if(seriesPoint == null || view == null) return; ExplodePoint(seriesPoint, view); int rowH = GetRowHandleByCompanyName(selectedCompanyName); if(rowH >= 0) watchListGridView.FocusedRowHandle = rowH; } void ExplodePoint(SeriesPoint seriesPoint, DoughnutSeriesView view) { view.ExplodedPoints.Clear(); view.ExplodedPoints.Add(seriesPoint); selectedCompanyName = seriesPoint.Argument.ToString(); } void volumeChart_ObjectHotTracked(object sender, HotTrackEventArgs e) { if(e.Object is DevExpress.XtraCharts.Series) return; e.Cancel = true; } void volumeChart_ObjectSelected(object sender, HotTrackEventArgs e) { if(e.Object is DevExpress.XtraCharts.Series) return; e.Cancel = true; } void PanelsCheckedChanged(object sender, XtraBars.ItemClickEventArgs e) { BarCheckItem item = e.Item as BarCheckItem; if(item == null) return; SetDockPanelVisibility(item); } void SetDockPanelVisibility(BarCheckItem item) { switch(item.Caption) { case "Watch List": if(!item.Checked) watchListDockPanel.Visibility = XtraBars.Docking.DockVisibility.Hidden; else watchListDockPanel.Visibility = XtraBars.Docking.DockVisibility.Visible; break; case "Transaction": if(!item.Checked) transactionGridDockPanel.Visibility = XtraBars.Docking.DockVisibility.Hidden; else transactionGridDockPanel.Visibility = XtraBars.Docking.DockVisibility.Visible; break; case "Top Volumes": if(!item.Checked) topVolumesDockPanel.Visibility = XtraBars.Docking.DockVisibility.Hidden; else topVolumesDockPanel.Visibility = XtraBars.Docking.DockVisibility.Visible; break; } } void watchListDockPanel_ClosedPanel(object sender, DockPanelEventArgs e) { watchListbarCheckItem.Checked = false; } void topVolumesDockPanel_ClosedPanel(object sender, DockPanelEventArgs e) { topVolumesbarCheckItem.Checked = false; } void transactionGridDockPanel_ClosedPanel(object sender, DockPanelEventArgs e) { transactionGridbarCheckItem.Checked = false; } void panelContainerTopVolumesAndTransaction_ClosedPanel(object sender, DockPanelEventArgs e) { transactionGridbarCheckItem.Checked = false; topVolumesbarCheckItem.Checked = false; } void watchListGridView_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e) { if(e.IsGetData) { CompanyTradingDataViewModel model = e.Row as CompanyTradingDataViewModel; if(model != null && model.VolumeDynamics != null) { List values = new List(); foreach(TradingDataViewModel dynamicItem in model.VolumeDynamics) values.Add(dynamicItem.Volume); e.Value = values; } } } SeriesPoint FindSeriesPointByName(string name) { for(int i = 0; i < volumeChart.Series[0].Points.Count; i++) { if(name == volumeChart.Series[0].Points[i].Argument.ToString()) return volumeChart.Series[0].Points[i]; } return null; } protected int GetRowHandleByCompanyName(string name) { for(int i = 0; i < watchListGridView.RowCount; i++) { if(watchListGridView.GetRow(i) != null && ((CompanyTradingDataViewModel)watchListGridView.GetRow(i)).CompanyName == name) return i; } return -1; } void bbiSwatches_ItemClick(object sender, ItemClickEventArgs e) { using(SvgSkinPaletteSelector svgSkinPaletteSelector = new SvgSkinPaletteSelector(this.FindForm())) { svgSkinPaletteSelector.ShowDialog(); } UpdateCustomColors(); } void helpBarItemButton_ItemClick(object sender, ItemClickEventArgs e) { AboutHelper.Show(ProductKind.DXperienceWin, new ProductStringInfoWin("Stock Market Trader Demo")); } } }