/// <summary> /// Renders the supplied "labelled control", i.e., control which has a label. /// </summary> /// <typeparam name="T">Type of control.</typeparam> /// <param name="writer">WpfXmlWriter to use to write the XAML.</param> /// <param name="control">Control to render alongside label.</param> /// <param name="controlRenderer">Control renderer to use to render the control.</param> public static void RenderLabelledControl <T>(WpfXmlWriter writer, T control, ControlRenderer <T> controlRenderer) where T : Control_t { bool isVertical = ((control as IParentable <StrategyPanel_t>).Parent.Orientation == Orientation_t.Vertical); // If this is a vertical StrategyPanel, we don't bother with a containing Grid - this provides nice alignment of labels and controls if (isVertical) { RenderControlLabel(writer, control, new GridCoordinate(control.Index, 0)); controlRenderer(control, new GridCoordinate(control.Index, 1)); } else { using (writer.New(WpfXmlWriterTag.Grid)) { writer.WriteAttribute(WpfXmlWriterAttribute.GridColumn, control.Index.ToString()); using (writer.New(WpfXmlWriterTag.GridColumnDefinitions)) { for (int n = 0; n < 2; n++) { using (writer.New(WpfXmlWriterTag.ColumnDefinition)) writer.WriteAttribute(WpfXmlWriterAttribute.Width, "Auto"); } } using (writer.New(WpfXmlWriterTag.GridRowDefinitions)) { using (writer.New(WpfXmlWriterTag.RowDefinition)) writer.WriteAttribute(WpfXmlWriterAttribute.Height, "Auto"); } RenderControlLabel(writer, control, StandardGridCoordinates.Label); controlRenderer(control, StandardGridCoordinates.Control); } } }
private static void RenderControlLabel(WpfXmlWriter writer, Control_t control, GridCoordinate gridCoordinate) { string label = control.Label; string forControl = control.Id; // Assumes that a control label will always be in the first cell of a 2 x 1 grid. if (!string.IsNullOrEmpty(label)) { using (writer.New(WpfXmlWriterTag.Label)) { writer.WriteAttribute(WpfXmlWriterAttribute.GridColumn, gridCoordinate.Column.ToString()); writer.WriteAttribute(WpfXmlWriterAttribute.GridRow, gridCoordinate.Row.ToString()); if (!string.IsNullOrEmpty(forControl)) { writer.WriteAttribute(WpfXmlWriterAttribute.Target, string.Format("{{Binding ElementName={0}}}", CleanName(forControl))); writer.WriteAttribute(WpfXmlWriterAttribute.IsEnabled, string.Format("{{Binding Path=Controls[{0}].Enabled}}", CleanName(forControl))); writer.WriteAttribute(WpfXmlWriterAttribute.Visibility, string.Format("{{Binding Path=Controls[{0}].Visibility}}", CleanName(forControl))); } writer.WriteAttribute(WpfXmlWriterAttribute.Content, label); } } }
private static void ProcessPanel(StrategyPanel_t panel, WpfXmlWriter writer, WpfControlRenderer controlRenderer, int rowOrColumn, ref int depth) { depth++; bool isVertical = (panel.Orientation == Orientation_t.Vertical); using (writer.New(DefaultNamespaceProvider.Atdl4netNamespace, "StrategyPanelFrame", DefaultNamespaceProvider.Atdl4netNamespaceUri)) { writer.WriteAttribute(WpfXmlWriterAttribute.Padding, "1"); writer.WriteAttribute(WpfXmlWriterAttribute.Margin, "1"); WritePanelAttributes(writer, panel); if (rowOrColumn == -1) { foreach (KeyValuePair <string, string> ns in controlRenderer.NamespaceProvider.CustomNamespaces) { writer.WriteNamespaceAttribute(ns.Key, ns.Value); } } else { writer.WriteAttribute((panel as IParentable <StrategyPanel_t>).Parent.Orientation == Orientation_t.Vertical ? WpfXmlWriterAttribute.GridRow : WpfXmlWriterAttribute.GridColumn, rowOrColumn.ToString()); } bool containsControls = (panel.Controls.Count > 0); // For grids containing a horizontal arrangement of controls, we add an empty column so we can set its width to "*" int childCount = containsControls ? panel.Controls.Count + (isVertical ? 0 : 1) : panel.StrategyPanels.Count; using (writer.New(WpfXmlWriterTag.Grid)) { if (depth == 1) { writer.WriteAttribute(WpfXmlWriterAttribute.DataContext, AtdlDataContext); } using (writer.New(WpfXmlWriterTag.GridRowDefinitions)) { int rowCount = isVertical ? childCount : 1; for (int n = 0; n < rowCount; n++) { using (writer.New(WpfXmlWriterTag.RowDefinition)) writer.WriteAttribute(WpfXmlWriterAttribute.Height, "Auto"); } } using (writer.New(WpfXmlWriterTag.GridColumnDefinitions)) { // Special treatment for vertical panels that contain controls - put in two columns, one for the label and // one for the control itself. int columnCount = isVertical ? (containsControls ? 2 : 1) : childCount; for (int n = 0; n < columnCount; n++) { using (writer.New(WpfXmlWriterTag.ColumnDefinition)) { if (containsControls) { writer.WriteAttribute(WpfXmlWriterAttribute.Width, (n < childCount - 1) ? "Auto" : "*"); } } } } // Note that a StrategyPanel_t can either contain other strategy panels, or controls but NOT BOTH. if (panel.StrategyPanels != null && panel.StrategyPanels.Count > 0) { int thisRowOrColumn = 0; foreach (StrategyPanel_t childPanel in panel.StrategyPanels) { ProcessPanel(childPanel, writer, controlRenderer, thisRowOrColumn, ref depth); thisRowOrColumn++; } } else { ProcessControls(panel, controlRenderer); // For horizontal strategy panels, put a dummy rectangle in the last column to trick // WPF to sizing the other columns to their control size. if (panel.Orientation == Orientation_t.Horizontal) { using (writer.New(WpfXmlWriterTag.Rectangle)) { writer.WriteAttribute(WpfXmlWriterAttribute.GridColumn, panel.Controls.Count.ToString()); } } } } } }