正在实现一个调度界面,本身用到了TreeList示例。
用的是11版的:WinForms\XtraTreeList\CS\TreeListMainDemo
现在,我想了解一下最新的技术,特别是实时变更工具条的部分。
DevExpress-13.2.6 中,找到一个grid的实时示例:
C:\Users\Public\Documents\DevExpress Demos 13.2\Components\WinForms\CS\GridMainDemo\bin\Debug
我们这次分析,两个重点:
1. 如何在gridview中加入一列,显示进度条。
2. 进度条如何动态改变
启动后,我们先来看看,如何填加后面的工具条:
namespace DevExpress.XtraGrid.Demos {
public partial class RealTimeSourceDemo : TutorialControl {
public RealTimeSourceDemo() {
InitializeComponent();
TutorialInfo.WhatsThisCodeFile = "CS\\GridMainDemo\\Modules\\RealTimeSource.cs";
TutorialInfo.WhatsThisXMLFile = "DevExpress.XtraGrid.Demos.CodeInfo.RealTimeSource.xml";
editorProgressBar = new RepositoryItemProgressBar { Minimum = 300, Maximum = 1000, ShowTitle = true, PercentView = false };
}
editorProgressBar = new RepositoryItemProgressBar { Minimum = 300, Maximum = 1000, ShowTitle = true, PercentView = false };
protected override void DoShow() {
base.DoShow();
isHide = false;
syncContext = SynchronizationContext.Current;
chtr = new ChangeThread(syncContext);
trackBar1.Value = 10;
PatchInterval();
//
realTimeSource = CreateRealTimeSource();
gridControl1.DataSource = realTimeSource;
//
timerShow = new Timer(TimerShowCallback, null, 0, 500);
backgroundTimer = new Timer(chtr.OnIdle, null, TimeSpan.Zero, TimeSpan.FromMilliseconds(10));
this.Disposed += RealTimeSourceDemo_Disposed;
chartControl1.Series["UPSDiagram"].Points.Clear();
tr = new Thread(chtr.Do);
tr.IsBackground = true;
tr.Start();
//
realTimeSource.DataSource = chtr.List;
//
gridView1.GridControl.RepositoryItems.AddRange(new RepositoryItem[] { editorProgressBar });
}
private void gridView1_DataSourceChanged(object sender, EventArgs e) {
GridColumn column = gridView1.Columns["DayVal"];
if(column == null || editorProgressBar == null)
return;
column.ColumnEdit = editorProgressBar;
}
column.ColumnEdit = editorProgressBar;
在这里下断,因为可以肯定,是需要改变这个值的。
public class MarketData {
double dayVal;
public double DayVal {
get { return Math.Round(dayVal, 1); }
private set { dayVal = value; }
}
}
找到:
public void Do() {
Random rndRow = new Random();
int postedOperation = 0;
do {
Stopwatch watch = Stopwatch.StartNew();
int row = rndRow.Next(0, collection.Count);
lock(lockObj) {
if(!useRealtimeSource) {
Interlocked.Increment(ref postedOperation);
context.Post((x) => {
collection[row].Update();
collection.ResetItem(row);
Interlocked.Decrement(ref postedOperation);
}, null);
} else {
collection[row].Update();
collection.ResetItem(row);
}
}
把这句注释掉后,启动,发现界面果然静止了。
那么,这里也就是我们要调研的第二个重点。
最难懂的就是这句:
realTimeSource.DataSource = chtr.List;
后面没看明白。
[DXToolboxItem(true)]
[ToolboxBitmap(typeof(ResFinder), "Bitmaps256.RealTimeSource.bmp")]
[Designer("DevExpress.Xpo.Design.RealtimeSourceDesigner, DevExpress.Xpo.v13.2.Design")]
[ToolboxTabName("DX.13.2: Data & Analytics")]
public class RealTimeSource : Component, IListSource, IDXCloneable
{
public static int SendQueueTimeout;
public RealTimeSource();
[RefreshProperties(RefreshProperties.All)]
[Category("Data")]
[AttributeProvider(typeof(IListSource))]
[DefaultValue("")]
public object DataSource { get; set; }
[RefreshProperties(RefreshProperties.All)]
[Editor("DevExpress.Design.RealTimeSourcePropertiesEditor, DevExpress.Design.v13.2", "System.Drawing.Design.UITypeEditor, System.Drawing")]
public string DisplayableProperties { get; set; }
[DefaultValue(false)]
public bool IgnoreItemEvents { get; set; }
[Browsable(false)]
public bool UseWeakEventHandler { get; set; }
public void CatchUp();
protected override void Dispose(bool disposing);
protected virtual object DXClone();
protected virtual RealTimeSource DXCloneCreate();
public static IEnumerable GetDisplayableProperties(object source);
public IList GetList();
public TimeSpan GetQueueDelay();
public void Resume();
public void Suspend();
}
chtr = new ChangeThread(syncContext);
RealTimeSource rts = new RealTimeSource();
realTimeSource.DataSource = chtr.List;
这个就是那个list
readonly BindingList
public class MarketData {
readonly static Random rnd = new Random();
const double MAX = 950;
const double MIN = 350;
public string Ticker { get; private set; }
double last;
public double Last {
get { return Math.Round(last, 1); }
private set { last = value; }
}
double chgPercent;
public double ChgPercent {
get { return Math.Round(chgPercent * 100, 2); }
private set { chgPercent = value; }
}
double open;
public double Open {
get { return Math.Round(open, 1); }
private set { open = value; }
}
double high;
public double High {
get { return Math.Round(high, 1); }
private set { high = value; }
}
double low;
public double Low {
get { return Math.Round(low, 1); }
private set { low = value; }
}
public DateTime Date;
public string Time {
get { return Date.ToLongTimeString(); }
}
double dayVal;
public double DayVal {
get { return Math.Round(dayVal, 1); }
private set { dayVal = value; }
}
没有完全看明白。但它就是能工作。
上面的属性,最终是如何映射到界面上的。