void InitThreadList(FrameGroup group, List <RowRange> rows) { ThreadList.Children.Clear(); if (group == null) { return; } int rowIndex = 0; ThreadList.RowDefinitions.Clear(); ThreadList.Margin = new Thickness(0, ThreadCanvas.HeaderHeight, 3, 1); for (int i = 1; i < ThreadList.ColumnDefinitions.Count; ++i) { ThreadList.ColumnDefinitions[i].SetBinding(ColumnDefinition.WidthProperty, new Binding("TimeWidth") { Source = canvas }); } Label workHeader = new Label() { Content = "Work(ms)", Margin = new Thickness(0, -2 * ThreadCanvas.HeaderHeight, 0, 0), ClipToBounds = false, FontSize = 12, FontWeight = FontWeights.Bold, VerticalAlignment = VerticalAlignment.Top }; Label waitHeader = new Label() { Content = "Wait(ms)", Margin = new Thickness(0, -2 * ThreadCanvas.HeaderHeight, 0, 0), ClipToBounds = false, FontSize = 12, FontWeight = FontWeights.Bold, VerticalAlignment = VerticalAlignment.Top }; Grid.SetColumn(workHeader, 1); Grid.SetRow(workHeader, 0); Grid.SetColumn(waitHeader, 2); Grid.SetRow(waitHeader, 0); ThreadList.Children.Add(workHeader); ThreadList.Children.Add(waitHeader); for (int threadIndex = 0; threadIndex < Math.Min(rows.Count, group.Board.Threads.Count); ++threadIndex) { RowRange range = rows[threadIndex]; if (range.MaxDepth > 0 && group.Threads[threadIndex].Events.Count > 0) { ThreadList.RowDefinitions.Add(new RowDefinition()); Thickness margin = new Thickness(3, 0, 0, ThreadCanvas.SpaceHeight); Label labelName = new Label() { Content = group.Board.Threads[threadIndex].Name, Margin = margin, Padding = new Thickness(), FontWeight = FontWeights.Bold, Height = range.Height, VerticalContentAlignment = VerticalAlignment.Center }; Label labelWork = new Label() { Margin = margin, Padding = new Thickness(), Height = range.Height, VerticalContentAlignment = VerticalAlignment.Center, DataContext = range, ContentStringFormat = "{0:0.00}" }; Label labelWait = new Label() { Margin = margin, Padding = new Thickness(), Height = range.Height, VerticalContentAlignment = VerticalAlignment.Center, DataContext = range, ContentStringFormat = "{0:0.00}" }; labelWork.SetBinding(Label.ContentProperty, new Binding("WorkTime") { Source = range }); labelWait.SetBinding(Label.ContentProperty, new Binding("WaitTime") { Source = range }); Grid.SetRow(labelName, rowIndex); Grid.SetColumn(labelName, 0); Grid.SetRow(labelWork, rowIndex); Grid.SetColumn(labelWork, 1); Grid.SetRow(labelWait, rowIndex); Grid.SetColumn(labelWait, 2); if (rowIndex++ % 2 == 0) { labelName.Background = ThreadCanvas.AlternativeBackgroundColor; labelWork.Background = ThreadCanvas.AlternativeBackgroundColor; labelWait.Background = ThreadCanvas.AlternativeBackgroundColor; } ThreadList.Children.Add(labelName); ThreadList.Children.Add(labelWork); ThreadList.Children.Add(labelWait); } } }
protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) { if (group == null) { return; } Rect area = new Rect(0, 0, AdornedElement.RenderSize.Width, AdornedElement.RenderSize.Height); drawingContext.PushClip(new RectangleGeometry(area)); drawingContext.DrawRectangle(Brushes.White, null, area); var threads = group.Threads; int rowIndex = 0; KeyValuePair <int, int> mainThreadInterval = new KeyValuePair <int, int>(); for (int threadIndex = 0; threadIndex < threads.Count; ++threadIndex) { List <EventFrame> frames = threads[threadIndex].Events; RowRange rowRange = rows[threadIndex]; if (rowRange.MaxDepth > 0 && frames.Count > 0) { KeyValuePair <int, int> interval = CalculateEventRange(frames, Position, Position + Range); if (threadIndex == group.Board.MainThreadIndex) { mainThreadInterval = interval; } Brush backgroundBrush = Brushes.White; if (rowIndex++ % 2 == 0) { backgroundBrush = AlternativeBackgroundColor; drawingContext.DrawRectangle(AlternativeBackgroundColor, null, new Rect(0, rowRange.Offset, AdornedElement.RenderSize.Width, rowRange.Height)); } for (int i = interval.Key; i <= interval.Value; ++i) { OnRenderFrame(drawingContext, frames[i], rowRange.Offset, rowRange.MaxDepth, backgroundBrush); } } } int mainThreadIndex = group.Board.MainThreadIndex; RenderFPSLines(drawingContext, group.Threads[mainThreadIndex].Events, mainThreadInterval); if (FocusedFrame != null) { RowRange rowRange = rows[FocusedFrame.Header.ThreadIndex]; Durable interval = FocusedNode != null ? FocusedNode.Entry as Durable : FocusedFrame.Header as Durable; Rect focusedRectangle = CalculateRect(interval, rowRange.Offset, rowRange.Height); drawingContext.DrawRectangle(null, selectedPen, focusedRectangle); } RenderSelectedScopes(drawingContext); drawingContext.Pop(); base.OnRender(drawingContext); }