I am trying to create buttons for a 10-foot GUI using WPF. Each button requires a little more data than just a single text string and an image, maybe 2-3 strings located in different positions and some imagery.
I have tried
<Button Height="52" HorizontalAlignment="Stretch" Name="button1" Width="407">
<Button.Content>
<DockPanel LastChildFill="True" HorizontalAlignment="Stretch">
<TextBlock Name="textBloczk2" Text="ABC" TextAlignment="Left" DockPanel.Dock="Left"/>
<TextBlock Name="textBlxock1" Text="CDE" TextAlignment="Right" DockPanel.Dock="Right"/>
</DockPanel>
</Button.Content>
</Button>
But no matter which inner container I use, the button seems to disregard the layout from the DockPanel and the combined text ends up in the middle of the button. Am I doing something wrong or should I be using a different outer container ?
The problem seems to be that the DockPanel's width is so small that the Right and Left panels are the same width as your TextBlocks.
This seems to work as expected (setting the width of the DockPanel):
<Button Height="52" HorizontalAlignment="Stretch" Name="button1" Width="407">
<Button.Content>
<DockPanel LastChildFill="True" Width="300">
<TextBlock Name="textBloczk1" Text="Left" DockPanel.Dock="Left" />
<TextBlock Name="textBlxock2" Text="Right" DockPanel.Dock="Right" />
<TextBlock Name="textBlxock3" Text="Top" DockPanel.Dock="Top" />
<TextBlock Name="textBlxock4" Text="Bottom" DockPanel.Dock="Bottom" />
</DockPanel>
</Button.Content>
</Button>
Try to add "HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" to your button. This way dockpanel will occupy all space inside the button.
Related
I have this button and I put some text in it using Content="1", there's a 15px padding around the top and 20px on the left side of the number, however the text appears to go outside of the button when it is resized.
this is what it normally is
and this is what happens when it resizes
if it helps any, here is the XAML code:
<Button x:Name="_btn1" Content="1" HorizontalAlignment="Center" Grid.Row="1" VerticalAlignment="Center" Width="214" FontSize="24" HorizontalContentAlignment="Left" VerticalContentAlignment="Top" Height="182" Margin="10,10,10,10" Background="#33999999" Click="DayClick" Padding="20,15,0,0"/>
Your content is not going outside; some portion of the button is hiding behind the content holder like StackPanel, Grid or whatever you are using.
Here are something you can do -
Use button's auto size instead of hard code size.
<Button x:Name="_btn1"
Content="1"
FontSize="24"
Background="SeaGreen"
Margin="10,10,10,10"
Grid.Row="1"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
Use ScrollViwer outside of your container.
<ScrollViewer>
<StackPanel>
<Button x:Name="_btn1"
Content="1"
FontSize="24"
Background="SeaGreen"
Width="214"
Height="182"
Padding="20,15,0,0"
Margin="10,10,10,10"
Grid.Row="1"
VerticalAlignment="Center"
HorizontalAlignment="Center"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Top"/>
</StackPanel>
</ScrollViewer>
You can't use ScrollViwer inside of a StackPanel
Use AdaptiveTrigger and change the buttons' properties as you need.
(Read the doc if you are not familiar - AdaptiveTrigger)
I think my title is a bit confusing so let me explain my question in detail.
I have a StackPanel with multiple Grids inside it. It basicly looks like a table with a "Header Grid" and a "Content Grid" below. The StackPanel itself is inside a ScrollViewer.
Whenever the user clicks on the "Header Grid" the corresponding "Content Grid" should be collapsed and visible vice versa.
Here is a short version of my table:
<ScrollViewer Margin="0,0,0,10">
<StackPanel>
<Grid x:Name="Header_Grid1" Height="24" Background="#BF101820" VerticalAlignment="Top" Margin="34,0,0,0" Cursor="Hand" >
<Label Content="Click me to show/hide Content_Grid1" Padding="5,0" VerticalContentAlignment="Center" Margin="5,0,0,0" Grid.ColumnSpan="2" Width="982"/>
</Grid>
<Grid x:Name="Content_Grid1" Height="100" Width="967" HorizontalAlignment="Right" Margin="0,5,0,0" RenderTransformOrigin="0.5,0.5">
<Label Content="some content" Foreground="#FF918F82" Padding="5,0" VerticalContentAlignment="Center" Margin="0,0,719,75"/>
<Label Content="some content" Foreground="#FF918F82" Padding="5,0" VerticalContentAlignment="Center" Margin="0,25,719,50"/>
</Grid>
<Grid x:Name="Header_Grid2" Height="24" Background="#BF101820" Width="1001" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,0,0">
<Label Content="Click me to show/hide Content_Grid2" Padding="5,0" VerticalContentAlignment="Center" Margin="5,0,0,0" Grid.ColumnSpan="2" Width="982"/>
</Grid>
<Grid x:Name="Content_Grid2" Height="100" Width="967" HorizontalAlignment="Right" Margin="0,5,0,0" RenderTransformOrigin="0.5,0.5">
<Label Content="some content" Foreground="#FF918F82" Padding="5,0" VerticalContentAlignment="Center" Margin="0,0,719,75"/>
<Label Content="some content" Foreground="#FF918F82" Padding="5,0" VerticalContentAlignment="Center" Margin="0,25,719,50"/>
</Grid>
</StackPanel>
</ScrollViewer >
Lets say the user clicks on "Header_Grid1" the "Content_Grid1" hides with an kinda "flow to the top" animation by reducing its size. Thats no problem at all - the thing is I´d like the "Header_Grid2" aswell as the "Content_Grid2" to flow to the top while the animation of hiding "Content_Grid1" is playing. "Header_Grid2" and "Content_Grid2" should not just pop to the place where "Content_Grid1" has been. It should rather happen in a smooth animation.
Hopefully someone understands what I mean. It´s pretty hard to explain...
Thanks
As far as I am aware you can't animate the collapsed method, but there are various tricks to get around that such as animating the opacity, size, location etc...
I somewhat of a WPF noob and am using a DockPanel to display the text content of an email in a TextBox in a ScrollViewer. The panel has a button bar and area for the email headers at the top, a button bar at the bottom, a panel at the right and the email itself should fill the remaining space dynamically:
[Banner at top, below which is a button bar and box with email headers. At the bottom is another full width button bar. The space between them is divided into a fixed-width panel at the right and a large text box for the email contents.]
http://rowlandsoftware.com/Screenshots/LongEmail.png
(The DockPanel sits inside a grid that provides the bit at the very top and is used when the email is not visible.)
The problem is that if the email is too short or too narrow, the textbox fails to fill the remaining width. In this screenshot, you can see some of the underlying stuff between the box and the panel:
[Between the text box and the panel is a column that is not filled. Part of what lies under it can be seen.]
http://rowlandsoftware.com/Screenshots/TooNarrow.png
The XAML is:
<DockPanel x:Name="EmailCanvas" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Visibility="Collapsed" Height="Auto">
<DockPanel x:Name="topButtonBar" DockPanel.Dock="Top" Height="50" Background="White">
<Button x:Name="btnReturn" DockPanel.Dock="Left" Content="Return to List" Click="btnReturn_Click" />
<Image Width="15" Source="Images/transparent.png" />
<Button x:Name="btnTextToggle" Content="Plain text" Click="btnTextToggle_Click" />
<Button x:Name="btnZoomOut" Content="Zoom Out" />
<Button x:Name="btnZoomIn" Content="Zoom In" />
<Image Width="150" DockPanel.Dock="Right" Source="Images/transparent.png" />
<Button x:Name="btnPrint" DockPanel.Dock="Right" Content="Print" Width="100"/>
<Image DockPanel.Dock="Right" Source="Images/transparent.png" />
</DockPanel>
<StackPanel x:Name="EmailHeaders" Orientation="Horizontal" DockPanel.Dock="Top" Width="Auto" Background="Linen">
<StackPanel Orientation="Vertical">
<TextBlock Text="Subject:" FontSize="16" />
<TextBlock Text="Time Sent:" FontSize="16"/>
<TextBlock Text="Other Recipients: " FontSize="16"/>
</StackPanel>
<StackPanel Orientation="Vertical">
<TextBlock x:Name="labSubject" Text="Subject:" FontSize="16" />
<TextBlock x:Name="labDateTime" Text="Sent:" FontSize="16"/>
<TextBlock x:Name="labSpare" Text="Other Recipients:" FontSize="14"/>
</StackPanel>
</StackPanel>
<DockPanel x:Name="bottomButtonBar" DockPanel.Dock="Bottom" Height="80" >
<Image Width="150" DockPanel.Dock="Left" Source="Images/transparent.png" />
<Button x:Name="btnDelete" DockPanel.Dock="Left" Content="Delete" />
<Image Width="150" Source="Images/transparent.png" />
<Button x:Name="btnSave" Content="Save" />
<Image Width="150" Source="Images/transparent.png" />
<Button x:Name="btnReply" Content="Reply" />
<Image Width="150" DockPanel.Dock="Right" Source="Images/transparent.png" />
</DockPanel>
<StackPanel DockPanel.Dock="Right" Orientation="Vertical" Background="White" Width="150">
<Button x:Name="btnAttachments" Content="Attachment"/>
</StackPanel>
<ScrollViewer x:Name="eTextViewer" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
<TextBox x:Name="eText" Background="White" HorizontalAlignment="Stretch" TextWrapping="Wrap" FontFamily="Verdana" FontSize="18" IsReadOnly="True" />
</ScrollViewer>
<!--Image Width="Auto" Height="Auto" DockPanel.Dock="Bottom" Source="Images/white.png" /-->
<WebBrowser x:Name="eHTML" Height="Auto" DockPanel.Dock="Top" Visibility="Collapsed" />
</DockPanel>
The box is extended only to fill the available height, not the width. The documentation for the DockPanel.LastChildFill Property says,
If you set the LastChildFill property to true, which is the default setting, the
last child element of a DockPanel always fills the remaining space, regardless
of any other dock value that you set on the last child element.
msdn.microsoft.com/en-us/library/system.windows.controls.dockpanel.lastchildfill%28v=vs.110%29.aspx
That does not appear to be the case: in my program it is only filling height, not width. LastFillChild=true is the default, but explicitly setting it to True or False doesn't make a blind bit of difference.
Interestingly, if you set DockPanel.Dock="Top" on the ScrollViewer, it fills the available width but not the height, leaving some of the underlying stuff showing between the text box and the bottom button bar. Again this is contrary to the documentation which says that the dock value set on the last child element is ignored.
Setting HorizontalAlignment="Stretch" to both the ScrollViewer and the TextBox and HorizontalContentAlignment="Stretch" to the ScrollViewer makes not a jot of difference.
So my question is, how can I ensure that the textbox fills the available space in the DockPanel even when the contents of the email are too short?
UPDATE: I have just noticed that if I remove the WebBrowser that is set initially to Visibility="Collapsed", then it works fine. I guess that its presence fools the DockPanel into regarding it as the LastChild even though it is Collapsed.
However, I need to toggle between displaying the email in the web browser and the text box, so removing it isn't an option. Both need to be treated as last child when they are visible. Any ideas?
UPDATE 2: So I wrap the scrollviewer and the web browser in another container, e.g. grid, which is the Last Child. Then I can toggle between the the two but they both fill the space.
Thanks guys. I wouldn't have got there without humiliating myself in public ;)
DockPanel will work, but beware of Collapsed items. Although the documentation says that a collapsed item has no effect on layout, with DockPanel it does if it is the LastChild.
The solution in my case was to add another container as the last child, and place the two items that I wanted to toggle between in that container. Then both will fill the remaining space in the panel.
I have a listbox with objects but I cannot scroll to the bottom of the page. What is the problem? This is the code that I'm using.
<Grid>
<Image Name="Nietcomment" Source="write.png" Width="70" Margin="350,-850,0,0" Tap="Login_popup" Visibility="Visible"/>
<Image Name="welcomment" Source="write2.png" Width="70" Margin="350,-850,0,0" Tap="Login_popup_remove" Visibility="Collapsed"/>
<ScrollViewer Name="scrollview" VerticalScrollBarVisibility="Visible" Margin="0,0,0,0" Foreground="Black">
<StackPanel>
<TextBlock x:Name="NTitelComment" Text="{Binding}" TextWrapping="Wrap" FontSize="25" Margin="10,0,10,0" Foreground="#FFE5001b"/>
<Line Stretch="Fill" Stroke="Black" X1="0" X2="1" Y1="0" Y2="0" Margin="10,0,10,0"/>
<TextBlock x:Name="tijdComment" Text="{Binding}" Margin="50,0,10,0" Foreground="Black"/>
<Image Height="20" Width="20" Margin="-380,-20,0,0" Source="/PostDateIcon.png"/>
<ListBox Margin="0,0,0,20" Name="lbComments" VerticalAlignment="Top" />
</StackPanel>
</ScrollViewer>
</Grid>
If you put a border around your ScrollViewer, can you see if it goes outside of the screen maybe? Will it help to set a fixed height of the Grid or ScrollViewer?
Keep in mind the phone has built in scroll, so your ScrollViewer maybe doesn't play well with it.
With so much fixed margins, your layout will be impossible to manage, especially when dealing with differents screen resolutions and especially with negative margins.
Anyway, right now, you have two scrollviewers, as your listbox contains one as well.
You should disable the listbox scrollviewer or it will prevent your page to scroll.
Just change your listbox:
<ListBox
Margin="0,0,0,20"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
Name="lbComments"
VerticalAlignment="Top" />
It will disable it's scrollviewer and allow it to scroll with the rest of the page.
I have the following setup
<grid>
<StackPanel>
<ListBox>
<TextBlock> ->Text you see getting cutt off<-
I have tried both just doing listbox.Add(String) and dynamically creating a TextBlock, assigning it text and then adding it to the listbox. Both produce identical results.
The image shows the listbox scrolled down half wayish. It appears the listbox has the correct height but the text inside hits some kind of limit.
UPDATE I changed the listbox to a scroll viewer and also hardcoded the Textblock in. Still same exact results
<Grid x:Name="theGrid" Grid.Row="1" Margin="12,0,10,0">
<StackPanel x:Name="TitlePanel" Grid.Row="0">
<TextBlock Text="Networking Tools" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
<StackPanel x:Name="stack">
<TextBlock x:Name="inputIndicator" Margin="12,0,0,0">
<Run Text="Enter IP OR Domain"/>
</TextBlock>
<telerikPrimitives:RadTextBox x:Name="input" Text="google.com" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Grid.Row="1" Height="84" Width="458"/>
<telerikInput:RadListPicker SelectionChanged="picker_SelectionChanged" x:Name="picker" HorizontalAlignment="Left" VerticalAlignment="Top" Width="436"/>
<Button Click="Button_Click" Content="Go" HorizontalAlignment="Left" VerticalAlignment="Top" Width="456"/>
<ScrollViewer HorizontalAlignment="Left" Height="392" Width="Auto" x:Name="list" VerticalAlignment="Top">
<TextBlock Name="content" Height="Auto" Width="Auto"/>
</ScrollViewer>
</StackPanel>
<UI:AdControl ApplicationId="test_client" AdUnitId="Image480_80" Height="80" Width="480"/>
</StackPanel>
<telerikPrimitives:RadBusyIndicator Margin="0,0,0,0" Height="106" Width="116" AnimationStyle="AnimationStyle1" x:Name="busyIndi" />
</Grid>
UI elements in Windows Phone 7 have a maximum renderable height and width of 2048 pixels. Any content that is larger than that gets clipped. The limit is only slightly higher for Windows Phone 8.
You did not mention how much text you are trying to show, but if it is very long, you could be hitting that limit.
There are a few ways you could handle this:
1) Break the text into smaller chunks and add individual TextBlocks to your StackPanel for each chunk.
2) Create a custom control that does the above for you, like this one: http://blogs.msdn.com/b/priozersk/archive/2010/09/08/creating-scrollable-textblock-for-wp7.aspx
3) Use a WebBrowser control instead of a TextBlock, and use its NavigateToString method to put your text in there.