/// /// <summary> /// Build columns (one for each years, dates, etc.)</summary> /// public void BuildColumns( bool animate = false, bool displayEvents = false, Size?newSize = null ) { double step; double width; double height; double left; FrameworkElement[] columns; FrameworkElement[] markers; int i; Utilities.Trace(this); if (newSize == null) { width = PixelWidth; height = PixelHeight; } else { width = newSize.Value.Width; height = newSize.Value.Height; } step = ColumnPixelWidth; if (m_columns == null || m_columns.Length != m_columnCount + EXTRA_COLUMNS) { columns = new FrameworkElement[m_columnCount + EXTRA_COLUMNS]; markers = new FrameworkElement[m_columnCount + EXTRA_COLUMNS]; if (m_columns != null) { Array.Copy(m_columns, columns, Math.Min(columns.Length, m_columns.Length)); for (i = columns.Length; i < m_columns.Length; ++i) { m_canvas.Children.Remove(m_columns[i]); } } if (m_columnMarkers != null) { Array.Copy(m_columnMarkers, markers, Math.Min(markers.Length, m_columnMarkers.Length)); for (i = markers.Length; i < m_columnMarkers.Length; ++i) { m_canvas.Children.Remove(m_columnMarkers[i]); } } m_columns = columns; m_columnMarkers = markers; } for (i = 0; i < m_columnCount + EXTRA_COLUMNS; ++i) { left = ColumnPixelWidth * (i - 1); if (m_columns[i] == null) { m_columns[i] = m_template.LoadContent() as FrameworkElement; m_columns[i].DataContext = null; m_canvas.Children.Add(m_columns[i]); } if (m_markerTemplate != null && m_columnMarkers[i] == null) { m_columnMarkers[i] = m_markerTemplate.LoadContent() as FrameworkElement; m_columnMarkers[i].DataContext = null; m_canvas.Children.Add(m_columnMarkers[i]); } } FixPositions(displayEvents, animate, true); }
/// <summary> /// Appies the binding to the breadcrumb item. /// </summary> public void ApplyBinding() { object item = DataContext; if (item == null) { return; } BreadcrumbItem root = this; DataTemplate template = HeaderTemplate; DataTemplateSelector templateSelector = HeaderTemplateSelector; if (templateSelector != null) { template = templateSelector.SelectTemplate(item, root); } if (template == null) { DataTemplateKey key = GetResourceKey(item); if (key != null) { template = TryFindResource(key) as DataTemplate; } } root.SelectedItem = null; HierarchicalDataTemplate hdt = template as HierarchicalDataTemplate; if (template != null) { root.Header = template.LoadContent(); } else { root.Header = item; } root.DataContext = item; if (hdt != null) { // bind the Items to the hierarchical data template: root.SetBinding(BreadcrumbItem.ItemsSourceProperty, hdt.ItemsSource); } BreadcrumbBar bar = BreadcrumbBar; if (bar != null) { if (TraceBinding == null) { TraceBinding = bar.TraceBinding; } if (ImageBinding == null) { ImageBinding = bar.ImageBinding; } } if (TraceBinding != null) { root.SetBinding(BreadcrumbItem.TraceProperty, TraceBinding); } if (ImageBinding != null) { root.SetBinding(BreadcrumbItem.ImageProperty, ImageBinding); } ApplyProperties(item); }
UIElement[] IView2DRenderer.Generate() { int nser = _dataInfo.nser; int npts = _dataInfo.npts; if ((nser == 0) || (npts == 0)) { return(null); } List <UIElement> objects = new List <UIElement>(); int num3 = 0; int num4 = 0; double width = _sz.Width; double height = _sz.Height; double num7 = width / ((double)_ncols); double num8 = height / ((double)_nrows); double num9 = 0.5 * Math.Min((double)(width / ((double)_ncols)), (double)(height / ((double)_nrows))); double naN = double.NaN; double startingAngle = 0.0; SweepDirection clockwise = SweepDirection.Clockwise; bool flag = false; Chart chart = base.Chart; double d = 0.0; if (chart != null) { startingAngle = PieOptions.GetStartingAngle(chart); clockwise = PieOptions.GetDirection(chart); flag = base.Chart.ChartType == ChartType.PieStacked; naN = PieOptions.GetOffset(chart); d = PieOptions.GetInnerRadius(chart); } if (double.IsNaN(naN)) { naN = base.Offset; } if (double.IsNaN(d) || (d == 0.0)) { d = base.InnerRadius; } for (int i = 0; i < nser; i++) { Point point = new Point(); double radiusX = num9 * base.Radius; double inner = d; if (flag) { inner = (((double)i) / ((double)nser)) * radiusX; radiusX *= ((double)(i + 1)) / ((double)nser); inner /= radiusX; } point = new Point((num4 - (0.5 * _ncols)) + 0.5, (num3 - (0.5 * _nrows)) + 0.5) { X = (num7 * point.X) + (0.5 * width), Y = (num8 * point.Y) + (0.5 * height) }; IDataSeriesInfo info = Series[i]; DataSeries series = info as DataSeries; series.Children.Clear(); objects.Add(series); double num16 = _dataInfo.SumsAbs[i]; double[,] values = info.GetValues(); if (!string.IsNullOrEmpty(series.Label)) { DataTemplate seriesLabelTemplate = null; if (chart != null) { seriesLabelTemplate = PieOptions.GetSeriesLabelTemplate(chart); } UIElement el = null; if (seriesLabelTemplate != null) { el = seriesLabelTemplate.LoadContent() as UIElement; FrameworkElement element2 = el as FrameworkElement; if (element2 != null) { element2.DataContext = series; } } if (el == null) { TextBlock block = new TextBlock(); block.Text = series.Label; IRenderer renderer = this; Control visual = renderer.Visual as Control; if (visual != null) { block.FontFamily = visual.FontFamily; block.FontSize = visual.FontSize; block.FontStretch = visual.FontStretch; block.FontStyle = visual.FontStyle; block.FontWeight = visual.FontWeight; } el = block; } Size size = Utils.GetSize(el); Canvas.SetLeft(el, point.X - (0.5 * size.Width)); if ((size.Height + radiusX) > (0.5 * num8)) { radiusX = (0.5 * num8) - size.Height; } if (flag) { Canvas.SetTop(el, (point.Y - (radiusX * inner)) - size.Height); } else { Canvas.SetTop(el, (point.Y - radiusX) - size.Height); } objects.Add(el); } double angle = startingAngle; double num18 = 0.0; if (naN > 0.0) { num18 = naN * radiusX; radiusX *= 1.0 - naN; } int num19 = (values != null) ? values.GetLength(1) : 0; for (int j = 0; j < num19; j++) { double num21 = values[0, j]; if (!double.IsNaN(num21) && (num21 != 0.0)) { ShapeStyle shapeStyle = StyleGen.GetStyle(j); double sweep = (Math.Abs(num21) / num16) * 360.0; if (sweep != 0.0) { if (clockwise == SweepDirection.Counterclockwise) { sweep = -sweep; } Point center = point; if ((num18 > 0.0) && (sweep != 360.0)) { double num23 = 0.017453292519943295 * (angle + (0.5 * sweep)); center.X += num18 * Math.Cos(num23); center.Y += num18 * Math.Sin(num23); } PieRenderContext rc = new PieRenderContext(); if (sweep < 0.0) { rc.PieInfo = new PieInfo(center, radiusX, radiusX, inner, angle + sweep, -sweep, 0.0, 0.0); } else { rc.PieInfo = new PieInfo(center, radiusX, radiusX, inner, angle, sweep, 0.0, 0.0); } DataPoint dp = series.CreateDataPoint(i, j); IPlotElement pe = null; if ((series.Symbol is PlotElement) && ((IPlotElement)series.Symbol).IsCompatible(this)) { pe = ((PlotElement)series.Symbol).Clone() as IPlotElement; } if ((pe == null) && (Symbol is PlotElement)) { pe = ((PlotElement)Symbol).Clone() as IPlotElement; } RenderElement(objects, pe, series, rc, shapeStyle, dp); if (series.ReadLocalValue(DataSeries.SymbolStrokeProperty) != DependencyProperty.UnsetValue) { ((PlotElement)pe).Stroke = series.SymbolStroke; } if (series.ReadLocalValue(DataSeries.SymbolStrokeThicknessProperty) != DependencyProperty.UnsetValue) { ((PlotElement)pe).StrokeThickness = series.SymbolStrokeThickness; } angle += sweep; } } } if (!flag) { num4++; if (num4 >= _ncols) { num4 = 0; num3++; } } } return(objects.ToArray()); }
/// <summary> /// Called when [series source changed]. /// </summary> /// <param name="oldValue">The old value.</param> /// <param name="newValue">The new value.</param> protected virtual void OnSeriesSourceChanged(StockInfoViewModel oldValue, StockInfoViewModel newValue) { this.Series.Clear(); this.Axes.Clear(); if (newValue != null) { DataTemplate axisCategoryXTemplate = GetCurentAxisCategoryXTemplate(null); DataTemplate axisCategoryYTemplate = GetCurentAxisCategoryYTemplate(null); DataTemplate axisFinancialIndicatorYTemplate = GetCurentAxisFinancialIndicatorYTemplate(null); // X Axis if (axisCategoryXTemplate != null) { // load data template content var axisCategoryX = axisCategoryXTemplate.LoadContent() as Axis; if (axisCategoryX != null) { axisCategoryX.DataContext = SeriesSource; this.Axes.Add(axisCategoryX); } } // Y Axis if (axisCategoryYTemplate != null) { // load data template content var axisCategoryY = axisCategoryYTemplate.LoadContent() as Axis; if (axisCategoryY != null) { axisCategoryY.DataContext = DataContext; this.Axes.Add(axisCategoryY); } } //Financial Indicator Y Axis if (axisFinancialIndicatorYTemplate != null) { // load data template content var axisFinancialIndicatorY = axisFinancialIndicatorYTemplate.LoadContent() as Axis; if (axisFinancialIndicatorY != null) { axisFinancialIndicatorY.DataContext = DataContext; this.Axes.Add(axisFinancialIndicatorY); } } StockInfoViewModel item = newValue; DataTemplate dataTemplate = GetCurentSeriesTemplate(item); if (dataTemplate != null) { // load data template content var series = dataTemplate.LoadContent() as Series; var financialIndicator = FinancialIndicatorSeriesTemplate.LoadContent() as Series; if (series != null) { // set data context series.DataContext = item; financialIndicator.DataContext = item; this.Series.Add(series); series.RefreshXAxis <CategoryXAxis>(this); series.RefreshYAxis <NumericYAxis>(this); this.Series.Add(financialIndicator); financialIndicator.RefreshXAxis <CategoryXAxis>(this); financialIndicator.RefreshYAxis <NumericYAxis>(this); } } } // TODO Listen for INotifyCollectionChanged with a weak event pattern }
/// <summary> /// Show an <see cref="Adornment"/> with reshape handles at each of the interesting points of the link's <see cref="Route"/>, /// if the link is selected and visible and if <see cref="Northwoods.GoXam.Part.CanReshape"/> is true. /// </summary> /// <param name="part"></param> /// <remarks> /// <para> /// This produces reshape handles at each point of the route, starting with /// <see cref="Northwoods.GoXam.Route.FirstPickIndex"/> and ending with /// <see cref="Northwoods.GoXam.Route.LastPickIndex"/>. /// Depending on whether <see cref="Northwoods.GoXam.Route.Orthogonal"/> is true, /// this will call <see cref="ReshapingBaseTool.SetReshapeBehavior"/> and the <c>Cursor</c> to /// limit the directions in which the user may drag the handle. /// </para> /// <para> /// You can change the template used to create each reshape handle by setting <see cref="Link.LinkReshapeHandleTemplate"/>. /// If that property is null, this uses a default template produces a small square. /// </para> /// </remarks> public override void UpdateAdornments(Part part) { Link link = part as Link; if (link == null) { return; // no Nodes } Adornment adornment = null; if (link.IsSelected) { FrameworkElement selelt = link.Path; if (selelt != null && link.CanReshape() && Part.IsVisibleElement(selelt)) { adornment = link.GetAdornment(ToolCategory); if (adornment == null) { Route route = link.Route; if (route != null) { IEnumerable <Point> pts = route.Points; int numpts = route.PointsCount; bool ortho = route.Orthogonal; if (pts != null && numpts > 2) { // LinkReshapeHandleTemplate: for each reshape handle, not for whole adornment DataTemplate template = link.LinkReshapeHandleTemplate; if (template == null) { template = Diagram.FindDefault <DataTemplate>("DefaultLinkReshapeHandleTemplate"); } LinkPanel panel = new LinkPanel(); int firstindex = route.FirstPickIndex; int lastindex = route.LastPickIndex; // don't bother creating handles for firstindex or lastindex for (int i = firstindex + 1; i <= lastindex - 1; i++) { // expand the DataTemplate to make a copy of a reshape handle FrameworkElement h = template.LoadContent() as FrameworkElement; // needs to be a FrameworkElement so we can set its Cursor if (h == null) { continue; } // identify this particular handle within the LinkPanel LinkPanel.SetIndex(h, i); // now determines its reshape behavior and cursor, depending on whether Orthogonal et al. if (i == firstindex) { // default ReshapeBehavior.None } else if (i == firstindex + 1 && ortho) { Point a = route.GetPoint(firstindex); Point b = route.GetPoint(firstindex + 1); if (Geo.IsApprox(a.X, b.X)) { SetReshapeBehavior(h, ReshapeBehavior.Vertical); h.Cursor = Part.SizeNSCursor; } else if (Geo.IsApprox(a.Y, b.Y)) { SetReshapeBehavior(h, ReshapeBehavior.Horizontal); h.Cursor = Part.SizeWECursor; } } else if (i == lastindex - 1 && ortho) { Point a = route.GetPoint(lastindex - 1); Point b = route.GetPoint(lastindex); if (Geo.IsApprox(a.X, b.X)) { SetReshapeBehavior(h, ReshapeBehavior.Vertical); h.Cursor = Part.SizeNSCursor; } else if (Geo.IsApprox(a.Y, b.Y)) { SetReshapeBehavior(h, ReshapeBehavior.Horizontal); h.Cursor = Part.SizeWECursor; } } else if (i == lastindex) { // default ReshapeBehavior.None } else { SetReshapeBehavior(h, ReshapeBehavior.All); h.Cursor = Part.SizeAllCursor; } panel.Children.Add(h); } adornment = new Adornment(); // for LinkReshapingTool.UpdateAdornments adornment.AdornedElement = selelt; adornment.Category = ToolCategory; adornment.Content = panel; // just provide the FrameworkElement as the Content and as the Visual Child adornment.LocationSpot = Spot.TopLeft; } } } if (adornment != null) { Point loc = link.GetElementPoint(selelt, Spot.TopLeft); adornment.Location = loc; adornment.RotationAngle = link.GetAngle(selelt); adornment.Remeasure(); } } } link.SetAdornment(ToolCategory, adornment); }
private void Update(bool useTransition) { if (_itemPresenter == null) { return; } DataTemplate itemTemplate = ItemTemplate; if (itemTemplate == null) { return; } object dataItem = null; DataList dataList = DataList; if (dataList != null) { dataItem = dataList.CurrentItem; } DetailViewItem item = new DetailViewItem(); Style itemContainerStyle = ItemContainerStyle; if (itemContainerStyle != null) { item.Style = itemContainerStyle; } item.DataContext = dataItem; if (dataItem != null) { FrameworkElement uiItem = itemTemplate.LoadContent() as FrameworkElement; if (uiItem != null) { item.Content = uiItem; } } Transition itemTransition = ItemTransition; if ((itemTransition == null) || (_item == null)) { useTransition = false; } if (useTransition == false) { _itemPresenter.Children.Clear(); } _itemPresenter.Children.Insert(0, item); if (useTransition) { if (((IAttachedObject)itemTransition).AssociatedObject != _itemPresenter) { ((IAttachedObject)itemTransition).Detach(); ((IAttachedObject)itemTransition).Attach(_itemPresenter); itemTransition.Completed += OnItemTransitionCompleted; } itemTransition.PlayEffect(EffectDirection.Forward); } if (dataItem != null) { if (_item == null) { VisualStateManager.GoToState(this, "NonEmpty", /* useTransitions */ true); } _item = item; } else { if (_item != null) { VisualStateManager.GoToState(this, "Empty", /* useTransitions */ true); } _item = null; } }
/// <summary> /// Overrides the default arrangement of a Canvas. /// </summary> /// <param name="arrangeSize">The largest possible size for the canvas.</param> /// <returns>The actual size used by this canvas.</returns> protected override Size MeasureOverride(Size constraint) { // This calculates the visible area of the virtual canvas. Note that the 'MeasureOverride' is called before the // 'OnRenderSizeChanged' so the rectangle used for clipping can't be used here because it hasn't been calclated // properly yet. Rect viewport = new Rect(this.rectangleGeometry.Rect.Location, constraint); // IMPORTANT CONCEPT: The FrameworkElements are recycled for performance. Creating the user interface elements and // adding and removing them from the canvas are very time consuming tasks. The XAML for the reports contains templates // used to create FrameworkElements for a given CLR type. It turns out that any CLR object of a given type can use any // FrameworkElement created for that given type. So a factory of sorts is created for building and reusing the // framework elements based on a CLR type. A screen is drawn by first reclaiming all the elements that are no longer // visible. These elements are not removed from the screen in the first pass. The secod pass draws the visible area // of the report using reclaimed elements when it can, creating new FrameworkElements when it can't. The important // performance kick here is that the elements are not actually removed from the screen during the reclaimation pass and // the drawing pass. All elements are put into this list when during the reclaimation cycle. If they are still in // this list after the drawing pass, then they are not visible and can be removed from the canvas. This is the // reclamation cycle. All the user interface elements that have become invisible are pushed back into the element // cache where they can be used again when the viewport is updated. foreach (UIElement uiElement in this.Children) { if (uiElement is FrameworkElement) { // This element will be examined to see if it needs to be recycled. FrameworkElement frameworkElement = uiElement as FrameworkElement; // The 'ReportCell' is the virtual information behind the user interface element and is attached to all the // visual elements in the canvas. It is used here to indicate whether the associated FrameworkElement is // invisible. ReportCell reportCell = DynamicReport.GetCell(frameworkElement); try { if (reportCell != null) { // This will test the virtual cell to see if it is invisible. Note that any cell that touches the right or // bottom edge of the viewport is considered to be invisible. There is no part of these cells that can // actually be seen, whereas the left and top edges are visible. Rect rect = reportCell.ActualRect; if (((viewport.Top > rect.Top || rect.Top >= viewport.Bottom) && (viewport.Top >= rect.Bottom || rect.Bottom > viewport.Bottom)) || ((viewport.Left > rect.Left || rect.Left >= viewport.Right) && (viewport.Left >= rect.Right || rect.Right > viewport.Right))) { // When the framework element has become invisible, it is placed back in the cache based on the CLR // type of the object it can display. It can be recycled for use with similar types when the new // viewport is constructed in the second pass. Type contentType = reportCell.Content.GetType(); Stack <FrameworkElement> elementStack; if (!this.elementCache.TryGetValue(contentType, out elementStack)) { elementStack = new Stack <FrameworkElement>(); this.elementCache.Add(contentType, elementStack); } elementStack.Push(frameworkElement); // This disconnects the visual element from the virtual ReportCell and the virtual ReportCell from the // visual element. DynamicReport.SetCell(frameworkElement, ReportCell.Empty); this.elementTable.Remove(reportCell); // The focus scope for this canvas must be cleared when the element that had the focus is recycled. // This method 'virtualizes' the handling of the focus. The virtual focus is saved in the 'IsFocused' // property of the ReportCell while the cell is invisible. When this virtual cell becomes visible // again, the keyboard focus will be given back to to user interface element used to instantiate the // virtual cell. if (reportCell.IsFocused) { FocusManager.SetFocusedElement(this.ReportGrid, null); if (frameworkElement.IsKeyboardFocusWithin) { Keyboard.Focus(this.ReportGrid); } } // All these bindings need to be released when a cell is no longer visible. There seems to be a very // practical limitation to how many binding updates can be done by the operating system. Failure to // release a binding when a user element is no longer visible will quickly result all the resources // being used. BindingOperations.ClearBinding(frameworkElement, Canvas.LeftProperty); BindingOperations.ClearBinding(frameworkElement, Canvas.TopProperty); BindingOperations.ClearBinding(frameworkElement, FrameworkElement.WidthProperty); BindingOperations.ClearBinding(frameworkElement, FrameworkElement.HeightProperty); BindingOperations.ClearBinding(frameworkElement, DynamicReport.IsEvenProperty); BindingOperations.ClearBinding(frameworkElement, DynamicReport.IsSelectedProperty); } } } catch (Exception exception) { String message = reportCell.ReportColumn == null ? "ReportColumn is null" : reportCell.ReportRow == null ? "ReportRow is null" : "not sure why"; EventLog.Error("{0}: {1} ({2})\n{3}", exception.GetType(), exception.Message, message, exception.StackTrace); } } } // This pass will construct the visible part of the canvas. The main idea is to find the virtual cells that appear in // the viewport and associate the cell with a visual element. If a visual element can be found in the cache, it is // used, otherwise one is created from a template. foreach (ReportRow reportRow in this.ReportGrid.Rows) { if (reportRow.IsEmpty) { continue; } // Only rows that appear in the visible part of the canvas are considered. Evaluating the rows this way quickly // removes the number of cells that need to be checked. if (((viewport.Top <= reportRow.Top && reportRow.Top < viewport.Bottom) || (viewport.Top < reportRow.Bottom && reportRow.Bottom <= viewport.Bottom))) { // At this point we have a row that is part of the visible canvas. This will see which of the columns are // visible. foreach (ReportColumn reportColumn in this.ReportGrid.Columns) { // Note that columns that fall on the right edge are excluded. Even though they appear to intersect with // the viewport, there is no part of these columns that's actally visible. if ((viewport.Left <= reportColumn.Left && reportColumn.Left < viewport.Right) || (viewport.Left < reportColumn.Right && reportColumn.Right <= viewport.Right)) { // The cell exists at a virtual location in the document coordinate system. They are instantiated and // added to the canvas when the become visible and are remove from the canvas when not visible. This // is how a very large document can be viewed with a relatively small number of visual elements and // bindings. ReportCell reportCell = reportRow[reportColumn]; // If this cell doesn't have a framework element associated with it, then one is either recycled // from the cache or created from a template. FrameworkElement frameworkElement; if (!this.elementTable.TryGetValue(reportCell, out frameworkElement)) { // Each Framework element will work with one and only one CLR type. The content of the // ReportCell determines what kind of FrameworkElement instance is used to display the data in // that cell. Type contentType = reportCell.Content.GetType(); // The CLR type of the content is used to find a stack of FrameworkElements that can be used to // display that content. Stack <FrameworkElement> elementStack; if (!this.elementCache.TryGetValue(contentType, out elementStack)) { elementStack = new Stack <FrameworkElement>(); this.elementCache.Add(contentType, elementStack); } // If there are no instances of a visual element that can be used to display the content of // this ReportCell, then one is generated from the template. Otherwise, a recycled element is // used. Note that all default focus styles are removed from visual elements on the canvas as // there these elements have a custom style applied which functions like the Microsoft Excel // focus and selection. if (elementStack.Count == 0) { DataTemplateKey dataTemplateKey = new DataTemplateKey(reportCell.Content.GetType()); DataTemplate dataTemplate = this.ReportGrid.Resources[dataTemplateKey] as DataTemplate; if (dataTemplate != null) { frameworkElement = dataTemplate.LoadContent() as FrameworkElement; frameworkElement.FocusVisualStyle = null; } } else { frameworkElement = elementStack.Pop(); } // This associates the visual element with the ReportCell that contains the information about // the location of that element in the virtual document coordinate space. The 'elementTable' // contains the reciprocal relation. DynamicReport.SetCell(frameworkElement, reportCell); this.elementTable.Add(reportCell, frameworkElement); // The data context for the XAML elements is the content of the cell, not the ReportCell. // This is done intensionally to hide the implementation details of how elements are positioned // on the screen. It is also done to simplify the programming model for the XAML code. frameworkElement.DataContext = reportCell.Content; // Bind the element's 'Left' property of the element to the column's position. Binding leftBinding = new Binding("ActualLeft"); leftBinding.Source = reportCell.ReportColumn; BindingOperations.SetBinding(frameworkElement, Canvas.LeftProperty, leftBinding); // Bind the element's 'Top' property of the element to the row's position. Binding topBinding = new Binding("ActualTop"); topBinding.Source = reportCell.ReportRow; BindingOperations.SetBinding(frameworkElement, Canvas.TopProperty, topBinding); // Bind the element's 'Width' property of the element to the column's width. Binding widthBinding = new Binding("ActualWidth"); widthBinding.Source = reportCell.ReportColumn; BindingOperations.SetBinding(frameworkElement, FrameworkElement.WidthProperty, widthBinding); // Bind the element's 'Height' property of the element to the row's height. Binding heightBinding = new Binding("ActualHeight"); heightBinding.Source = reportCell.ReportRow; BindingOperations.SetBinding(frameworkElement, FrameworkElement.HeightProperty, heightBinding); // Bind the element's 'IsSelected' property to the cell's property. This property is used to // highlight the selected cells. Binding isSelectedBinding = new Binding("IsSelected"); isSelectedBinding.Source = reportCell; BindingOperations.SetBinding(frameworkElement, DynamicReport.IsSelectedProperty, isSelectedBinding); // Bind the 'Height' property of the element to the row's 'IsEven' property. This property is // generally used to shade every other line to make it easier to follow the information on a // row. Binding evenBinding = new Binding("IsEven"); evenBinding.Source = reportCell.ReportRow; BindingOperations.SetBinding(frameworkElement, DynamicReport.IsEvenProperty, evenBinding); } // New and recycled elements need to be added to the canvas to become part of the visible report. if (frameworkElement.Parent == null) { this.Children.Add(frameworkElement); } // The logical (and keyboard) focus is restored to the element that has the virtual focus when the // virtual cell is made visible again. Note that the logical focus is only moved when the canvas // has the keyboard focus. This prevents a scenario where the canvas grabs the input focus away // from another window when the input focus is made visible again. if (reportCell.IsFocused) { if (this.IsKeyboardFocusWithin) { if (FocusManager.GetFocusedElement(this.ReportGrid) != frameworkElement) { FocusManager.SetFocusedElement(this.ReportGrid, frameworkElement); } } } } } } } // At this point, all the elements that can be recycled have been recycled. The remaining elements on the canvas that // are not associated with a virtual report element need to be removed. for (int index = 0; index < this.Children.Count;) { UIElement uiElement = this.Children[index]; if (DynamicReport.GetCell(uiElement) == ReportCell.Empty) { this.Children.RemoveAt(index); } else { index++; } } // The base class takes care of the hard work of measuring the visible user interface elements on the canvas. return(base.MeasureOverride(constraint)); }
public OptionColumnInfo(DataGridColumn column, DataGridExtend grid) { if (column == null) { return; } Column = column; if (column is DataGridTemplateColumn) { var boundColumn = column as DataGridTemplateColumn; if (boundColumn != null) { DataTemplate dt = boundColumn.CellTemplate as DataTemplate; if (dt != null) { if (dt.DataType != null) { string dataType = dt.DataType.ToString(); TemplateColumnType templateType = (TemplateColumnType)Enum.Parse(typeof(TemplateColumnType), dataType); System.Windows.Data.Binding binding = new Binding(); switch (templateType) { case TemplateColumnType.HyperLink: StackPanel sp = dt.LoadContent() as StackPanel; TextBlock tb = sp.Children[3] as TextBlock; InlineUIContainer il = tb.Inlines.FirstInline as InlineUIContainer; Label lbl = il.Child as Label; Run r = lbl.Content as Run; binding = BindingOperations.GetBinding(r, Run.TextProperty); break; case TemplateColumnType.TextBlock: TextBlock tb1 = dt.LoadContent() as TextBlock; binding = BindingOperations.GetBinding(tb1, TextBlock.TextProperty); break; case TemplateColumnType.TextBox: TextBox tb2 = dt.LoadContent() as TextBox; binding = BindingOperations.GetBinding(tb2, TextBox.TextProperty); break; case TemplateColumnType.CheckBox: CheckBox cb = new CheckBox(); if (dt.LoadContent() is CheckBox) { cb = dt.LoadContent() as CheckBox; } else if (dt.LoadContent() is Grid) { Grid gd = dt.LoadContent() as Grid; if (gd.Children.Count > 1) { cb = gd.Children[1] as CheckBox; } } if (cb.IsThreeState) { IsSpecialState = true; binding = BindingOperations.GetBinding(cb, CheckBox.ContentProperty); } else { binding = BindingOperations.GetBinding(cb, CheckBox.IsCheckedProperty); } break; //case TemplateColumnType.MultiComboBox: // try // { // MultiComboBox multiCbb = dt.LoadContent() as MultiComboBox; // binding = BindingOperations.GetBinding(multiCbb, MultiComboBox.TextProperty); // } // catch (Exception ex) // { // binding = null; // } // break; case TemplateColumnType.ComboBox: Grid gd2 = dt.LoadContent() as Grid; ComboBox com = gd2.Children[0] as ComboBox; if (!string.IsNullOrWhiteSpace(com.DisplayMemberPath)) { binding = BindingOperations.GetBinding(com, ComboBox.SelectedItemProperty); StringPath = com.DisplayMemberPath; } else { binding = BindingOperations.GetBinding(com, ComboBox.SelectedItemProperty); } break; } if (binding != null && binding.Path != null && !string.IsNullOrWhiteSpace(binding.Path.Path)) { System.Reflection.PropertyInfo propInfo = null; if (!string.IsNullOrWhiteSpace(StringPath)) { System.Reflection.PropertyInfo propInfo2 = null; if (grid.FilterType != null) { propInfo2 = grid.FilterType.GetProperty(binding.Path.Path); } propInfo = propInfo2.PropertyType.GetProperty(StringPath); } else { if (grid.FilterType != null) { propInfo = grid.FilterType.GetProperty(binding.Path.Path); } } //if (propInfo != null) //{ IsValid = propInfo != null ? true : false; PropertyPath = binding.Path.Path; Converter = binding.Converter; PropertyType = propInfo != null ? propInfo.PropertyType : typeof(string); if (Converter != null) { PropertyConvertType = Converter.Convert(null, null, null, null).GetType(); } ConverterCultureInfo = binding.ConverterCulture; ConverterParameter = binding.ConverterParameter; //} //else //{ //} } } } } else if (column.SortMemberPath != null && column.SortMemberPath.Length > 0) { PropertyPath = column.SortMemberPath; PropertyType = grid.FilterType.GetProperty(column.SortMemberPath).PropertyType; } } else { var boundColumn = column as DataGridBoundColumn; if (boundColumn != null) { System.Windows.Data.Binding binding = boundColumn.Binding as System.Windows.Data.Binding; if (binding == null || binding.Path == null) { return; } if (binding != null && !string.IsNullOrWhiteSpace(binding.Path.Path)) { System.Reflection.PropertyInfo propInfo = null; if (grid.FilterType != null) { propInfo = grid.FilterType.GetProperty(binding.Path.Path); } if (propInfo != null) { IsValid = true; PropertyPath = binding.Path.Path; Converter = binding.Converter; PropertyType = propInfo != null ? propInfo.PropertyType : typeof(string); if (Converter != null) { PropertyConvertType = Converter.Convert(null, null, null, null) == null ? null : Converter.Convert(null, null, null, null).GetType(); } ConverterCultureInfo = binding.ConverterCulture; ConverterParameter = binding.ConverterParameter; } else { //if (System.Diagnostics.Debugger.IsAttached && System.Diagnostics.Debugger.IsLogging()) // System.Diagnostics.Debug.WriteLine("Jib.WPF.Controls.DataGrid.JibGrid: BindingExpression path error: '{0}' property not found on '{1}'", binding.Path.Path, boundObjectType.ToString()); } } } else if (column.SortMemberPath != null && column.SortMemberPath.Length > 0) { PropertyPath = column.SortMemberPath; PropertyType = grid.FilterType.GetProperty(column.SortMemberPath).PropertyType; } } }