Most simple FrameworkElement to handle HorizontalAlignment and VerticalAlignment? - c#

This is Silverlight.
Initial goal is to display a random element in a Popup with some VerticalAlignment and HorizontalAlignment. I do not want to use VerticalOffset or HorizontalOffset, because there is more to what I really want to do, including some complex bindings.
First attempt was:
<Popup>
<Button
Height="135"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom" />
</Popup>
Second attempt was:
<Popup
Height="135"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom">
<Button />
</Popup>
Both were a failure: the Button was always on Top and not Stretch (HorizontalAlignment and VerticalAlignment didn't work).
So I had the idea to encapsulate the element in a simple FrameworkElement:
<Popup>
<Border>
<Button
Height="135"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom" />
</Border>
</Popup>
And it is working.
But I had to use Border in this example, when I could have done it with Grid and many other FrameworkElement (but not with Canvas or Viewbox or Popup). I'd like to know what is the most simple, efficient and processor-friendly transparent FrameworkElement to encapsulate another element with working HorizontalAlignment and VerticalAlignment? Is it:
Border? (like the above example)
UserControl?
ContentControl?
ContentContainer?
some custom and basic MyFrameworkElement? (might need help for most basic implementation)
something else like Grid?

WPF controls come in two flavors: Ones that interact with users (like accept user clicks like a button, or display text like a text block) and containers that control placement and layout of the previous ones.
Container controls are usually designed to lay out their children in a specific manner. For example, Canvases lay out children by X, Y, Width & Height values. Each one has a specific use, so you must read the documentation or tutorials for these container controls and understand how each works in order to select the appropriate one for a task.
In your case, you want the button to fill all available space in the popup (it seems, it isn't that clear). I know that the Grid does this by default. So I would do the following:
<Popup><Grid><Button /></Grid></Popup>

Related

Let user resize control (textbox, specifically) in Canvas UWP

I have a canvas with a button that the user can press to add a new textbox to the canvas. How can I make it so the user can resize the text box by clicking and dragging on any of the corners of the textbox. Because the textbox is created in the C# code (not XAML), I would prefer code in C# not XAML.
Thanks
EDIT: My question is different than the one referenced because it is in UWP not WPF. These have very different controls. I would appreciate if you could translate the UWP information into UWP C#
You can use Thumb control instead of a textbox. The thumb control provides the functionality for you to write code to customize the drag and drop behavior. A simple code would be:
<Canvas x:Name="test">
<Thumb Width="100" Height="100">
<Thumb.Template>
<ControlTemplate>
<TextBlock HorizontalAlignment="Center" Text="12345"/>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Canvas>
A more complex sample could be found from this SO thread from Jay's answer. But please notice you need to customize the logic yourself in order to make it resize like what you need. The reference is just a direction.

How to set button in side stackpanel to right edge in windows 10 universal app development

I an new to windows app development,i searched for this but not found any where.I need the button at right edge and Stretch the textbox till buttons start.But I am unable to set the button to Right edge.
How to acheve this.
A stackpanel works like a container. If you define layout properties on your stackpanel, then the objects inside your stackpanel cannot be displayed outside of the stackpanel's limits.
For example :
If I set my row and column number in my stackpanel,
<StackPanel Grid.Row="0" Grid.Column="2" Name="Version" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top">
<Label Grid.Column="4" Grid.Row="6" Name="Ver" Content="V." HorizontalAlignment="Right" />
<TextBlock Name="Vers" Text="1.0" TextAlignment="Right" />
</StackPanel>
Then the row/column properties set on my label are ignored and the 'HorizontalAlignment="Right"' will place my label on the right side of the stackpanel, not the grid.
A solution may be to remove your button from your stackpanel, you are then free to place your button anywhere on the grid.
Another solution can be to expand your stackpanel's limits.
To do so, you can use the Grid.ColumnSpan property or simply set your stackpanel on the right of the grid.
Hope that helped.

How to bind to a control's literal actual width (including its margins)?

According to some folks, the actual width is obtained using ActualWidth attribute as shown in the example below. It makes sense but I seem to experience contradicting behavior.
<Canvas Width="{Binding ActualWidth,ElementName=Expy}">
<Expander x:Name="Expy"
HorizontalAlignment="Left"
Margin="0,0,0,0"
VerticalAlignment="Top" ...>
...
</Expander>
</Canvas>
In the setup above, the behavior is consistent with the expectations and, although tightly squeezed together, the next element in the panel containing the canvas is not overlapped by it's predecessor.
However, if I change the margins to a bit wider, I can clearly see that the canvas intrude on the next element, estimatingly by the same number of pixies that I requested in the margin attribute. So it'd appear that the ActualWidth isn't the actual width but the width without the margin.
Am I confusing something here and if so, what?
How to obtain and bind to the actaully actual, rendered width?
The linked answer says:
ActualWidth accounts for padding and margins ...
This is incorrect. The ActualWidth includes only the padding, not the margin (same with ActualHeight).
A comment that has been left on that answer by somebody else provides the appropriate correction.
This XAML code illustrates the issue:
<Window x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<TextBlock x:Name="First" Text="Some text" Padding="10" Margin="0,0"
HorizontalAlignment="Left" Background="Yellow" />
<TextBlock Text="{Binding ActualWidth, ElementName=First}" />
<TextBlock x:Name="Second" Text="Some text" Padding="10" Margin="10,0"
HorizontalAlignment="Left" Background="LimeGreen" />
<TextBlock Text="{Binding ActualWidth, ElementName=Second}" />
</StackPanel>
</Window>
If you run this you will see that both of the "Some text" text blocks have the same ActualWidth value despite the second one having horizontal margins applied to it.
You asked how you could take this into account. There is no way of doing this through binding because the ActualWidth property doesn't include the margin as already stated. What you can do is apply the margin to the parent element (the canvas) instead of applying it to the expander.
In other words, instead of doing this:
<Canvas Width="{Binding ActualWidth,ElementName=Expy}">
<Expander x:Name="Expy" ... Margin="10" ... >
...
</Expander>
</Canvas>
do this:
<Canvas Width="{Binding ActualWidth,ElementName=Expy}" Margin="10">
<Expander x:Name="Expy" ... >
...
</Expander>
</Canvas>
Yes Konrad. You are confusing.
Whenever we mean Actual(Height/Width), it is the rendered one. You were correct in that. However, Actual(Height/Width) values gets initialized after the WPF Layout process which includes Measure and Arrange stages and that is something you need to understand first to get to the real cause of the problem.
At first, Binding anything with Actual values will never give you desired results because by doing this you are violating WPF Layout chain. As per WPF Layout stages, in Measure stage WPF gets the specified size (for e.g. values specified in height and width) for each control in the layout and then in the Arrange stage it actually allocates controls to the layout in the best possible way. The size specified is subject to vary after the Arrange stage.
Also, it should be noted that Actual parameters include rendered size plus padding value (but not margin). In your example, I guess the other panel next to the Expander control is the reason behind the problem you reported. I can confirm only when I see the entire layout.
But as a precautionary measure, you can always stop using Actual parameters for bindings. You can definitely get it worked out using Width and Height values for binding.
You cannot include the margin to your ActualWidth. A solution for this would be to use DesiredSize.Width or DesiredSize.Height. This will take into account the Margin. But it's a UIElement.

Adding elements to a panel in c#!

quick question, in a c# Windows Presentation Foundation How can i add some elements to a Panel so i can easily hide all the elements (Text, Labels...) by just hiding the panel it self?
I have already tried to just put panels over the elements to hide them but i don't think that would be a neat solution because i would also hide all the other elements under it.
I need this because i am trying to have different forms in the same place and on the base of what the user types the items should appear. I don't want it to open a new window.
Thanks!
Assuming all your elements are in the same container, just set the Visibility property of the container to "Collapsed". Ideally, this would be by binding to a bool and using the BoolToVisibility converter provided in WPF.
If they are NOT in the same container, you are a bit out of luck. You will need to set/bind each of the element's visibility properties separately, but using the same techniques as above.
If you place all of the elements you want on that panel you can tell that panel to be invisible or visible and all of the elements on that panel will hide or show accordingly. For ease of use when you are programming you can right click on the panel and choose send back or bring forward and this will help you navigate your form while programming.
Panel is a base class and has a Visibility property
Panel Properties
<StackPanel x:Name="pnl1" Grid.Row=0 Visibility="Collapsed">
<TextBlock x:Name="tbTime" />
<TextBlock x:Name="tbDate" />
</StackPanel>
<StackPanel x:Name="pnl2" Grid.Row=2 Visibility="Visible">
<TextBlock x:Name="tbTime2" />
<TextBlock x:Name="tbDate2" />
</StackPanel>

How to display Groupboxes in order of selection

I need to a collection of groupboxes varying on the user selection. for example; there will be 7 groupboxes, the user can enable however many they want and in what order they want. So i want the selected groupbox B to appear at the bottom of the previously selected groupbox A yet when A is unselected B moves up the form to where A was.
In my mind i want it to behave similar to HTML items.
This will be done in WPF, coding in C#.
You can stack these groupboxes in a stackpanel with orientation=vertical. You can then set the Visibility of the groupboxex to the users decision and wpf will make the rest for you "by magic".
Little sample here:
<StackPanel Orientation="Vertical">
<GroupBox x:Name="First" Visibility="Visible" Header="First">
<Label>First</Label>
</GroupBox>
<GroupBox x:Name="Second" Visibility="Collapsed" Header="Second">
<Label>Second</Label>
</GroupBox>
<GroupBox x:Name="Third" Visibility="Visible" Header="Third">
<Label>Third</Label>
</GroupBox>
</StackPanel>
Put your GroupBoxes in a collection of some kind and databind that collection to a cusomised ListView. Whenever the selected state of a GroupBox changes update the view of that ListView to sort them based on your requirements. Unfortunately I am not good enough to provide a working sample in the time I have, sry.

Categories

Resources