I need to hide a TextBlock that is child of a Border and is added to a Grid. The following code dynamically add the Border and the TextBlock to the Grid. Then if the Grid contain more than 5 children it hide the firsts children. It work correctly to hide the border but the TextBlock (the child of Border) remain visible.
Any idea where could be the problem? Thanks!
Border TextBorder = new Border();
TextBorder.BorderBrush = new SolidColorBrush(_settings.TextColor);
TextBorder.BorderThickness = new Thickness(0,0,0,2);
TextBorder.Padding = new Thickness(0, 10, 0, 10);
RowDefinition rd = new RowDefinition();
rd.Height = GridLength.Auto;
myGrid.RowDefinitions.Add(rd);
TextBlock uc = new TextBlock();
uc.Text = "Test";
TextBorder.Child = uc;
Grid.SetRow(TextBorder, myGrid.RowDefinitions.Count -1);
myGrid.Children.Add(TextBorder);
if (myGrid.Children.Count > 5)
{
Border border = (Border)myGrid.Children[myGrid.Children.Count - 6];
border.Visibility = Visibility.Hidden;
border.Child.Visibility = Visibility.Hidden;
}
Update
The code work correctly. The problem was in OnRender event of the TextBlock that draw the text with some graphic effect. I though that if the control is invisible OnRender should not be raised but it seams that it is raised also when the control is invisible. I have not found a way to prevent OnRender to be raised, nor ClipToBound nor Invisible work. So I give up with this approach and I just check in OnRender if the TextBlock is in the visible area of the container.
first of all, I think what you do is something you should not do!
But here is how you can do it (btw this assumes you only add Borders to your grid):
if (myGrid.Children.Count > 5)
{
(myGrid.Children[myGrid.Children.Count - 6] as Border).Visibility = Visibility.Hidden;
}
also i recommend to remove not to hide the child as it will otherwise stay in existance without any point
myGrid.Children.Remove(myGrid.Children[0]);
Related
I'm making a Button at runtime with a ViewBox and inside the ViewBox I'm adding a TextBlock. It all works fine, except I can't seem to get the text to left-align. After some fiddling, I realized this is because the TextBlock isn't the full width of the button.
var row = new RowDefinition();
OrdersGrid.RowDefinitions.Add(row);
var button = new Button();
button.HorizontalAlignment = HorizontalAlignment.Stretch;
button.VerticalAlignment = VerticalAlignment.Stretch;
button.MaxHeight = 40;
button.Background = (Brush)System.Windows.Application.Current.Resources["OrangeGradient"];
button.BorderThickness = new Thickness(.1);
button.Margin = new Thickness(.1);
OrdersGrid.Children.Add(button);
Grid.SetColumn(button, 0);
Grid.SetRow(button, rowNumber);
Viewbox vb = new Viewbox();
vb.StretchDirection = StretchDirection.Both;
vb.HorizontalAlignment = HorizontalAlignment.Stretch;
TextBlock tb = new TextBlock();
tb.HorizontalAlignment = HorizontalAlignment.Stretch;
tb.Text = rowNumber + " - " + CustomerName;
tb.Padding = new Thickness(0);
tb.TextAlignment = TextAlignment.Left;
vb.Child = tb;
button.Content = vb;
If I change tb.HorizontalAlignment = HorizontalAlignment.Stretch; to tb.Width = 400; it left-aligns. However, I have no guarantee that that is the correct size, but it does narrow the problem down to the width of the TextBlock. How can I make the TextBlock (And ViewBox) the full width of the Button?
Set the HorizontalContentAlignment property of the Button to Left:
button.HorizontalContentAlignment = HorizontalAlignment.Left;
Why do you want to make the contents the full width of the button? What visual or functional difference would that make? I don't see anything in your code that would require that. If the TextBlock had a background brush of its own, that would be a reason, but it doesn't.
If you absolutely did need to left center the text within something stretched, put a Border around the ViewBox inside the button, set Button.HorizontalContentAlignment = Stretch, and set ViewBox.HorizontalAlignment = Left.
The bottom line here is that the Button's content is by default centered in the Button's content area, and Button.HorizontalContentAlignment controls that. Its default value is Center. If you want to force the content to stretch, set it to Stretch.
If you really just want to left justify the content, just use mm8's answer. Quick and easy.
There's some spacing between the Buttons I add to my TableLayoutPanel. I removed the border in the Button and set the Margin and Padding to 0 in the Panel. But I continue getting that spacing.
tableLayoutPanel.RowCount is set to 8 and the Rows collection I've added 8 rows with Size Type Absolute.
Am I missing something? Here's the code:
private void FillSelectLayout()
{
tableLayoutPanelSelect.Controls.Clear();
tableLayoutPanelSelect.RowStyles.Clear();
tableLayoutPanelSelect.RowCount = 8;
for (int i = 0; i < 8; i++)
{
Button buttonSelector = new Button();
buttonSelector.Height = 64;
buttonSelector.Width = 100;
buttonSelector.FlatStyle = FlatStyle.Flat;
buttonSelector.FlatAppearance.BorderSize = 0;
buttonSelector.BackColor = Color.Yellow;
tableLayoutPanelSelect.Controls.Add(buttonSelector, 0, i);
}
}
Here's how it's displayed:
To remove the space between buttons in cells, it's enough to set dock property of them to fill and then remove default margins of buttons:
var b = new Button();
b.Dock = DockStyle.Fill;
b.Margin = new Padding(0);
Note:
Usually it's better to set Dock property of controls which you host in cells to Fill. This way your controls will follow TableLayouPanel sizing rules which you set for columns and rows.
TableLayoutPanel use Margin property of control to set the location of control in cell. So If you don'n want to set Dock and you prefer to set the Size manually, it's enough to set the Margin only.
I .. set the Margin and Padding to 0 in the Panel.
Why didn't you remove the Margin in the Buttons instead:
buttonSelector.Margin = new Padding(0);
MSDN:
The Margin property defines the space around the control that keeps
other controls a specified distance from the control's borders.
I faced the same problem while using different control in TableLayoutPanel
You can do this
Go to Design View
Click on the properties
GoTo Columns, When you click text box besides Columns, a button (...) appears on extreme right, click it
A pop up window appears, Select AutoSize (Instead of Absolute or Percentage).
In the same window in Show: select Rows and again select Autosize.
Click okay and you are done.
When I add Popup to my XAML like this
<Grid>
...other controls
<Popup x:Name="popup" Width="200" Height="200" >
</Popup>
</Grid>
It behaves as though the popup is there even though I did not toggle IsOpen = true (but the space is blank so no popup is visible)
However when I do the same from the code behind (add a popup) like this, it works like it should, it doesn't interfere with any controls (i.e. shift them) and it pops up as expected over top the other controls.
Popup p = new Popup();
// Create some content to show in the popup. Typically you would
// create a user control.
Border border = new Border();
border.BorderBrush = new SolidColorBrush(Colors.Black);
border.BorderThickness = new Thickness(0);
StackPanel panel1 = new StackPanel();
panel1.Background = new SolidColorBrush(Colors.);
Button button1 = new Button();
button1.Content = "Close";
button1.Margin = new Thickness(5.0);
button1.Click += new RoutedEventHandler(Feedback_Click);
TextBlock textblock1 = new TextBlock();
textblock1.Text = "The popup control";
textblock1.Margin = new Thickness(5.0);
panel1.Children.Add(textblock1);
panel1.Children.Add(button1);
border.Child = panel1;
// Set the Child property of Popup to the border
// which contains a stackpanel, textblock and button.
p.Child = border;
// Set where the popup will show up on the screen.
p.VerticalOffset = 400;
p.HorizontalOffset = 150;
// Open the popup.
p.IsOpen = true;
Does anyone know how I can accomplish the same thing in the XAML?
There are two ways of using a Popup. It can be an overlay control or it can be defined in the layout (or added to the tree) and it will take space like a standard control.
To have an overlay popup but avoid defining the layout in code-behind and still u, two techniques are often used:
1) defining the popup content as a separate user control. Your event handlers like Feedback_Click would now be definded in code-behind of the UserControl
var p = new Popup { Child = new MyControl() };
p.IsOpen = true;
2) defining the popup content simply in xaml in ResourceDictionary.
I'm using a Dockpanel via C# & WPF to display 2 user controls
The Left UserControl is a Datagrid with Filters (Called Filter)
The Right UserControl is a Custom Form That will change depending on what type of Data the user is viewing.
I'm setting the Dockpanel via this code
private void SetMasterDock(UIElement MyFilter, UIElement NewViewer)
{
MasterDock.Children.Clear();
DockPanel.SetDock(MyFilter, Dock.Left);
DockPanel.SetDock(NewViewer, Dock.Right);
MasterDock.Children.Add(MyFilter);
MasterDock.Children.Add(NewViewer);
}
All the above works as coded.
Now the Change I'm looking for (If possible)
I'd like to know what / how to enable the User to be able to Adjust the Scaling of the two Usercontrols. so if they wish to see More or less of one side or the other, they can just Click & Slide a Divider bar so they can adjust their view to their personal preferences.
ETA: New Code
MasterDock.Children.Clear();
Grid SplittableGrid = new Grid();
GridSplitter MovableDevider = new GridSplitter(); MovableDevider.Background = Brushes.Blue; MovableDevider.HorizontalAlignment = HorizontalAlignment.Right; MovableDevider.VerticalAlignment = VerticalAlignment.Stretch; MovableDevider.Width = 5;
ColumnDefinition LeftDefinition = new ColumnDefinition(); LeftDefinition.Width = new GridLength(200);
ColumnDefinition RightDefinition = new ColumnDefinition(); RightDefinition.Width = new GridLength(1,GridUnitType.Star);
SplittableGrid.ColumnDefinitions.Add(LeftDefinition);
SplittableGrid.ColumnDefinitions.Add(RightDefinition);
Grid.SetColumn(MyFilter, 0);
Grid.SetColumn(MovableDevider, 0);
Grid.SetColumn(NewViewer, 1);
SplittableGrid.Children.Add(MyFilter);
SplittableGrid.Children.Add(MovableDevider);
SplittableGrid.Children.Add(NewViewer);
DockPanel.SetDock(SplittableGrid, Dock.Left);
MasterDock.Children.Add(SplittableGrid);
in winforms the control you are looking for is the splitcontainer. However in WPF this is done using grid + gridSplitter. both of those controls are in the default toolbox.
I have a form with a scrollable panel and two controls sitting right on top of each other - one visible one not. Based on a certain condition when that form is activated I might swap the visible properties of the two controls. These controls are at the bottom of the scrollable panel. If when I leave that form I leave it scrolled to the bottom, go change the condition that will cause the controls' visibility to swap and go back to that form the visible control will have dropped about 200px down the page leaving a large gap. Anyone know what could be causing this? I tried resetting the scrollbar position to the top on form close but that just causes a smaller gap and sometimes the control to move higher into other controls. Any ideas?
Here is an example that reproduces the problem. If the mouse is moved over the red label, the visibility of button2 is changed to true which causes the scroll jumps back up to Button1.
public class Form123456 : Form {
public Form123456() {
Controls.Add(new UC1());
}
public class UC1 : UserControl {
Button b1 = new Button { Text = "Button1" };
Label lb = new Label { Text = "_", AutoSize = true, BackColor = Color.Red };
Button b2 = new Button { Text = "Button2", Visible = false };
Button b2b = new Button { Text = "x" };
Button b3 = new Button { Text = "Button3" };
public UC1() {
AutoScroll = true;
Dock = DockStyle.Fill;
b1.Location = new Point(0, 200);
b2.Location = new Point(0, 600);
lb.Location = new Point(70, 600);
b2b.Location = new Point(90, 600);
b3.Location = new Point(0, 800);
Controls.Add(b1);
Controls.Add(b2);
Controls.Add(lb);
Controls.Add(b2b);
Controls.Add(b3);
lb.MouseEnter += delegate {
b2.Visible = true;
};
lb.MouseLeave += delegate {
b2.Visible = false;
};
}
}
}
To fix it, one solution is to add this code:
protected override Point ScrollToControl(Control activeControl) {
return this.AutoScrollPosition;
}
Solution from:
Why does clicking in a text box cause an AutoScroll panel to scroll back to the top?
No repro. Sounds to me that you are doing more than just changing the Visible property. Whenever you assign the Location property, you have to add the AutoScrollPosition to compensate for the scroll state. Post code if this doesn't help.
Have you verified the order that you change visibility of the two controls?
The scroll bars on a container with auto scroll set to true will appear and disappear depending on the position of controls that are outside of the visible area of the control. Controls that are invisible do not count.
So in your case if you make both controls invisible at anytime, the scroll bars will disappear. They will come back when one control is made visible. So to make sure you don't have a jump in scroll bar position and controls position you should make sure that at no time are both controls invisible. Another solution is to have a pseudo-visible control on the container. That is a control that has its visibility set to true but it is not actually visible for the user (for example a dot of the color of the background, a label with no text ...). Position this control in the furthest position x,y and the scroll bars will never disappear..