Right, so I'm drawing what looks like a DataGrid on a standard WPF Grid panel.
The content controls are essentially TextBlock controls inside Border controls at Grid row and column references to create the overall layout, added at runtime and using the usual Grid.SetRow() and Grid.SetColumn() methods
Not every X and Y grid reference has a content control - this is determined by a runtime definition of the data for the grid. I use offset values to mark whether an XY pair is part of the "headers" of the rows/columns or whether the grid reference is part of the "data" section.
I am trying to put a gradient background across the whole of the "data" section. I was using a Grid control with the gradient brush set as follows:
//Grey background to show for "grey cells"
Grid greyBackground = new Grid()
{
Background = (Brush)this.Resources["BackgroundBrush"],
VerticalAlignment = System.Windows.VerticalAlignment.Stretch,
HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
Width = double.NaN,
Height = double.NaN,
};
greyBackground.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
greyBackground.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
Grid.SetColumn(greyBackground, _vm.Definition.ColumnOffset);
Grid.SetRow(greyBackground, _vm.Definition.RowOffset);
Grid.SetColumnSpan(greyBackground, _vm.Definition.Columns - _vm.Definition.ColumnOffset);
Grid.SetRowSpan(greyBackground, _vm.Definition.Rows - _vm.Definition.RowOffset);
cellGrid.Children.Add(greyBackground);
This however is not visible at all. And I have no idea why.
Any idea how I can display a gradient background painted control over these row/column locations, underneath the other "data" controls?
Related
I have a WinForms-Application where I want to add UserControls dynamicly docking to the top:
this.Controls.Clear();
this.Controls.Add(myCustomControl(){Title="first", content="first text", Dock=DockStyle.Top});
this.Controls.Add(myCustomControl(){Title="second", content="very long text, where......", Dock=DockStyle.Top});
now myCostumControl [YELLOW] is a userControl with the following content:
TopTitle [PINK]: A Label, docked to the top
BottomContent [GREEN]: A Panel, Fills out the rest of the Control below the TopTitle (Dockstyle Fill)
TextContent [BLUE]: A multiline Textbox, docked (fill) within the Panel.
So it looks like this:
Now what I need to achieve is that the Height from myCustomControl is according to the Text-Content of the "TextContent" - TextBox, so I can stack multiple Controls. So if there is only a "Hello World" in it, the height should be small, if I put the Windows EULA in it it should be very long.
I already tried messing around with all "AutoSize"-properties I could get my hands on, but the Textbox either disappeared completely or it hat no effect.
I also tried resizing the Textbox on Change:
Size size = TextRenderer.MeasureText(txtContent.Text, txtContent.Font);
txtContent.Height = size.Height;
No success, either
To make your composite control auto-size, perform these settings:
Add a Label to user control and set AutoSize of label to false and set it's height to a suitable height and set its Dock to top.
Add a TextBox to user control and set its Dock to Fill.
override SetBoundsCore and calculate the preferred size of control:
protected override void SetBoundsCore(int x, int y, int width, int height,
BoundsSpecified specified)
{
var flags = TextFormatFlags.WordBreak | TextFormatFlags.NoPrefix;
var proposedSize = new Size(width, int.MaxValue);
var size = TextRenderer.MeasureText(textBox1.Text, textBox1.Font,
proposedSize, flags);
height = Math.Max(size.Height, textBox1.Font.Height) + label1.Height + 5;
base.SetBoundsCore(x, y, width, height, specified);
}
Handle TextChanged event of the TextBox to refresh size of control when content text changes:
void textBox1_TextChanged(object sender, EventArgs e)
{
SetBoundsCore(Left, Top, Width, Height, BoundsSpecified.Size);
}
Here is the result:
If you want myCustomControlto be autosized, then obvioulsy, you cannot use fill docking for any child controls as docking set the size of the child according to parent size and you want parent size to adjust according to child size.
So you should either use a table layout or a flow layout for the child. If you use a table, then, you have to use auto-size for the rows that should adapt.
Then the whole layout control could be set to auto-size and should be docked at top (or maybe anchored).
An you can the parent to display a vertical scrollbar if the layout control does not fit in visible area.
I need to return width of GridComboBoxColumn based on the maximum length of combotext mentioned below, which is loaded as its ItemsSource . The maximum combotext is "Frankfurt a.M.-Germany-Country" and the width is calculted in WinRT and WPF as follows:
//Calculate width for maximum display text ComboBox items
TextBlock TextBlock = new TextBlock()
{
FontFamily = FontFamily,
Margin = Margin,
FontSize = FontSize,
TextWrapping=TextWrapping.NoWrap
};
//Set the TextBlock display text to combo items text and initialize Height and Width for TextBlock
TextBlock.Text = DisplayText;
var parentBorder = new Border { Child = TextBlock };
TextBlock.MaxHeight = size.Height;
TextBlock.MaxWidth = double.MaxValue;
this.DataGrid.UpdateLayout();
//Measuer the width and Height of parentBorder
parentBorder.Measure(new Size(TextBlock.MaxWidth, TextBlock.MaxHeight));
parentBorder.Child = null;
return parentBorder.DesiredSize.Width;
In WPF, the width returned as 182.46 and in WinRT the width is returned as 248 . But in WinRT the column width fit with ComboBox, in WPF the ComboBox does not fit inside the column width. Please advise how the size is measured in both WPF and WinRT?
I am using a flowlayoutpanel which have a lot of buttons per logic sake. I'm having an issue of when I resize the window, I'm not I'm not able to see all the buttons lined up horizontally when the window gets smaller. Instead as the window gets smaller, the buttons drops down to the next line. Can anyone help me on how to resolve this issue? I just want the buttons to line up horizontally, when the window gets smaller, have a horizontal scrollbar. Below is what I have.
fLayoutPnl.Controls.Add(btn1);
// snipped adding buttons from 2 to 15
fLayoutPnl.Controls.Add(btn16);
fLayoutPnl.Dock = System.Windows.Forms.DockStyle.Top;
fLayoutPnl.Location = new System.Drawing.Point(0, 10);
fLayoutPnl.Name = "fLayoutPnl";
fLayoutPnl.Size = new System.Drawing.Size(1245, 30);
If you dock the flowlayoutpanel on the top, it take the size of the parent control.
So if you want a horizontal scroll, you need to set the AutoScrollMinSize of the form (or usercontrol).
Otherwise, you can do this :
this.AutoScroll = true;
this.fLayoutPnl.Dock = System.Windows.Forms.DockStyle.None;
this.fLayoutPnl.AutoSize = true;
this.fLayoutPnl.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.fLayoutPnl.Location = new System.Drawing.Point(0, 10);
this.fLayoutPnl.Name = "fLayoutPnl";
this.fLayoutPnl.Size = new System.Drawing.Size(1245, 30);
fLayoutPnl.WrapContents = false;
This would solve the issue. If a scroll bar is needed, set the MinimumSize property of the panel, after which the scroll bar should appear
To view all the contents of flow layout panel by scrolling vertically, set AutoScroll property to True and don't forget to set WrapContents property to True.
If the contents are to be viewed by scrolling horizontally, set AutoScroll property to True and don't forget to set WrapContents property to False.
In my Windows Phone 7 app, I would like to have a TextBlock followed by a CheckBox. From left to right.
I am doing this programmatically, and I can do this with the following code:
StackPanel ControlStackPanel = new StackPanel();
ControlStackPanel.Orientation = System.Windows.Controls.Orientation.Horizontal;
TextBlock ControlTextBlock = new TextBlock();
ControlTextBlock.Text = #"ControlNameGoesHere";
CheckBox ControlCheckBox = new CheckBox();
ControlCheckBox.Margin = new Thickness(0, 0, 0, 0);
ControlCheckBox.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
ControlStackPanel.Children.Add(ControlTextBlock);
ControlStackPanel.Children.Add(ControlCheckBox);
However, I would actually like the TextBlock element to align to the left side of the screen, and the CheckBox element align to the right side of the screen. How can I do this?
Do I need to add a grid programmatically? The reason I don't want to do this in XAML is that adding these stackpanels is going to be an iterative process, and it just works better with my code if I do it all programmatically.
I've googled a heck of a lot, but haven't had much luck.
Many thanks!
Brett
A content control only has one alignment at once. All the controls within it are aligned according to it's horizontal alignment. You may wish to have two content controls with the different alignments inside a larger outer container.
Grid
StackPanel left
Control
StackPanel right
Control
Try to place your controls into columns of Grid. ControlTextBox should go to the first column of the Grid, ControlCheckBox - into the second one.
Here's some code:
TextBlock ControlTextBlock = new TextBlock();
ControlTextBlock.Text = #"ControlNameGoesHere";
ControlTextBlock.SetValue(Grid.ColumnProperty, 0);
ControlTextBlock.VerticalAlignment = System.Windows.VerticalAlignment.Top;
CheckBox ControlCheckBox = new CheckBox();
ControlCheckBox.Margin = new Thickness(0, 0, 0, 0);
ControlCheckBox.SetValue(Grid.ColumnProperty, 1);
ControlCheckBox.VerticalAlignment = System.Windows.VerticalAlignment.Top;
ColumnDefinition FirstColumn = new ColumnDefinition();
FirstColumn.Width = System.Windows.GridLength.Auto;
ColumnDefinition SecondColumn = new ColumnDefinition();
SecondColumn.Width = System.Windows.GridLength.Auto;
Grid ContentGrid = new Grid();
ContentGrid.ColumnDefinitions.Add(FirstColumn);
ContentGrid.ColumnDefinitions.Add(SecondColumn);
ContentGrid.Children.Add(ControlTextBlock);
ContentGrid.Children.Add(ControlCheckBox);
I am using drag and drop functionality in an application and I need to change the look of a Grid based on the location of the drag point.
For example, I would like to be able to call something like the following that would change the border to only show the bottom, or the top,etc. This example would be that when there is a drag operation performed over Grid, the top border of the grid would be the only one set to a thickness of 5 and would be black.
private void Grid_DragOver(object sender,DragEventArgs e)
{
Grid grid = (Grid)sender;
Border border = new Border();
border.BorderBrush = Brushes.Black;
border.BorderThickness = new Thickness(0,5,0,0);
border.Child = grid;
}
http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.margin.aspx
Edit: Border color http://msdn.microsoft.com/en-us/library/system.windows.controls.border.borderbrush.aspx