I'm having a problem, visible at runtime and in Expression Blend, where the text blocks (not text boxes, buttons, or custom controls) in my layout grid keep pushing themselves outside their cells, rendering them invisible. If I touch any of their properties in Blend (such as incrementing and then decrementing one of the margins), they become visible in Blend, but still not at runtime. Below is a screenshot showing the phenomenon in Blend. You see the design guides pointed to where the control should be, but its actual location above the top of the canvas.
Controls are offset in Blend http://tinyurl.com/y9ttscf
Update:
Below I've posted the XAML, with the VisualStateGroups removed (since they add considerable complexity to the XAML and the problem manifests itself without them). The control selected above is "loginTextBlock" below.
<navigation:Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
mc:Ignorable="d" xmlns:UserControls="clr-namespace:MyClient.UserControls" xmlns:MyClient_Controls="clr-namespace:MyClient.Controls;assembly=MyClient.Controls" xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit" x:Class="MyClient.Views.Login"
d:DesignWidth="640" d:DesignHeight="480"
Title="Login"
>
<Grid x:Name="LayoutRoot">
<Grid HorizontalAlignment="Center" Margin="0,16,0,0" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="loginTextBlock" HorizontalAlignment="Center" Style="{StaticResource HeaderTextStyle}" VerticalAlignment="Center" Text="Login" Grid.ColumnSpan="2" Margin="0,8"/>
<TextBlock x:Name="usernameTextBlock" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Row="1" Text="User name:" TextWrapping="Wrap"/>
<TextBox x:Name="usernameTextBox" HorizontalAlignment="Left" Margin="8,8,0,8" VerticalAlignment="Center" Width="175" Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" TabIndex="0" FontSize="16" Height="28" Padding="2"/>
<TextBlock x:Name="passwordTextBlock" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Row="2" Text="Password:" TextWrapping="Wrap"/>
<PasswordBox x:Name="passwordBox" HorizontalAlignment="Left" Margin="8,8,0,8" VerticalAlignment="Center" Width="175" Grid.Column="1" Grid.Row="2" TabIndex="1" FontSize="16" Height="28" Padding="2"/>
<Button x:Name="okButton" Height="32" HorizontalAlignment="Center" Margin="0,16,0,0" VerticalAlignment="Top" Width="96" Content="OK" Grid.Row="3" TabIndex="2" Click="okButton_Click" Grid.ColumnSpan="2"/>
<UserControls:StatusTextBlockControl x:Name="verifyingStatusTextBlockControl" Margin="8,16,8,8" VerticalAlignment="Center" Grid.Row="4" HorizontalAlignment="Center" Grid.ColumnSpan="2" Text="Verifying credentials..."/>
<MyClient_Controls:LoginAttemptsCounter x:Name="loginAttemptsCounter" HorizontalAlignment="Center" Margin="8" VerticalAlignment="Center" Grid.ColumnSpan="2" Grid.Row="5" FirstFailureMessage="Please re-enter your Windows credentials.
After 2 more failed attempts, your account will be locked." Height="30"/>
</Grid>
</Grid>
</navigation:Page>
For some reason, when my "LoginAttemptsCounter" control is in the grid (at the bottom), it was messing up the TextBlock controls. Instead, I changed my layout to wrap the grid within a StackPanel and place the LoginAttemptsCounter in the StackPanel below the grid rather than in the grid's bottom row. That has worked.
The key thing is that my custom control can't be within the same container (either the StackPanel or the Grid) as the TextBlocks.
Related
Beginner with WPF here. I am trying to make a window that has a panel in the bottom of the window, that contains two buttons side by side in the bottom right corner. basically, like this picture. but, all I have managed to code is this. The bottom panel is a mess. How do I make it look like my original design? I have tried dragging within the designer, but it is not working.
My XAML below (for the entire window - because I'm a noob. feel free to correct any mistakes).
<Window x:Class="ace.views.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ace.views"
mc:Ignorable="d"
Title="Welcome to My software " Height="450" Width="800">
<Grid VerticalAlignment="top" HorizontalAlignment="Stretch">
<StackPanel Margin="30">
<TextBlock FontFamily="Segoe UI" FontSize="30" Foreground="#0078D7">Welcome to my software</TextBlock>
<TextBlock FontFamily="Segoe UI" FontSize="20" TextWrapping="Wrap" Margin="0 20">This application is here to help you to teach vocabulary to your students, and to keep track of their progress.</TextBlock>
<TextBlock FontFamily="Segoe UI" FontSize="20" TextWrapping="Wrap" Margin="0 20">Let's get started in the next step.</TextBlock>
</StackPanel>
<Grid Background="#EFEFEF" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button x:Name="cmdSubmit"
HorizontalAlignment="Center"
VerticalAlignment="Stretch" Grid.Row="0" Width="120" Content="Next" />
<Button x:Name="cmdReset"
HorizontalAlignment="Center"
VerticalAlignment="Stretch" Grid.Row="0" Width="120" Content="Cancel" Grid.Column="1"/>
</Grid>
</Grid>
</Window>
Two RowDefinitions in outer Grid should do the trick for Window layout.
Changing ColumnDefintions for inner Grid will help to pin buttons to the right side.
<Window x:Class="ace.views.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ace.views"
mc:Ignorable="d"
Background="#EFEFEF"
Title="Welcome to My software " Height="450" Width="800">
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Margin="30">
<TextBlock FontFamily="Segoe UI" FontSize="30" Foreground="#0078D7">Welcome to my software</TextBlock>
<TextBlock FontFamily="Segoe UI" FontSize="20" TextWrapping="Wrap" Margin="0 20">This application is here to help you to teach vocabulary to your students, and to keep track of their progress.</TextBlock>
<TextBlock FontFamily="Segoe UI" FontSize="20" TextWrapping="Wrap" Margin="0 20">Let's get started in the next step.</TextBlock>
</StackPanel>
<Grid Grid.Row="1" Background="#EFEFEF">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button x:Name="cmdSubmit" HorizontalAlignment="Center" Grid.Column="1" Width="120" Margin="5" Content="Next"/>
<Button x:Name="cmdReset" HorizontalAlignment="Center" Grid.Column="2" Width="120" Margin="5" Content="Cancel"/>
</Grid>
</Grid>
</Window>
Change your first Grid from Top to Stretch.
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
Put a Grid.RowDefinitions there...
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
Your second Grid, point it to Grid.Row=1
<Grid Background="#EFEFEF" Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Margin="0,0,0,0">
To find out more about RowDefinitions, Here
I'm trying to add a border to some controls in XAML - the problem is, whenever I apply wrapping a certain element it wraps the whole window, probably on the first grid element?
This also happens when I try to use it around the WebBrowser. Any suggestions?
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="RAT-t00l" Height="850" Width="700">
<Grid x:Name="BigGrid" HorizontalAlignment="Right" Width="682">
<TextBox Name="txt_Log" HorizontalAlignment="Left" Height="657" Margin="4,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="417" IsReadOnly="True"/>
<Button Name="btn" Click="btn_Connect_Click" Background="LightGreen" Content="Connect" HorizontalAlignment="Left" Margin="266,680,0,0" VerticalAlignment="Top" Width="75"/>
<Button Name="btn_disc" Click="btn_Disconnect_Click" Background="Pink" Content="Disconnect" HorizontalAlignment="Left" Margin="346,680,0,0" VerticalAlignment="Top" Width="75"/>
<Button Name="btn_fetch" Click="btn_Fetch_Click" Content="Fetch data" HorizontalAlignment="Left" Margin="266,707,0,0" VerticalAlignment="Top" Width="155" Height="24"/>
<Button Name="btn_eraseLog" Click="btn_EraseLog_Click" Content="Erase log from target" HorizontalAlignment="Left" Margin="266,736,0,0" VerticalAlignment="Top" Width="155" Height="25"/>
<WebBrowser
Name="map"
HorizontalAlignment="Left"
Height="347"
Margin="426,10,0,0"
VerticalAlignment="Top"
Width="246"
LoadCompleted="wb_LoadCompleted"
/>
Here's the border. Meaning to wrap only the grid inside.
<Border Name="mask" CornerRadius="20" Height="auto" Width="auto" BorderThickness="1" BorderBrush="Black">
<Grid x:Name ="GeneralGrid" Margin="426,362,10,291" ShowGridLines="True" Background="LightGray">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="61*" ></ColumnDefinition>
<ColumnDefinition Width="185*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Name="IP">IP</TextBlock>
<TextBlock Name="ISP" Grid.Row="1">ISP</TextBlock>
<TextBlock Name="Location" Grid.Row="2">Location</TextBlock>
<TextBlock Name="Longitude" Grid.Row="3">Longitude</TextBlock>
<TextBlock Name="Latitude" Grid.Row="4">Latitude</TextBlock>
</Grid>
</Border>
</Grid>
</Window>
I would recommend that you do NOT continue to use the Visual Studio Designer as you have been. It does a very poor job of creating the XAML that we actually want. For example, your UI elements have all got an exact Margin set on them (thanks to the VS Designer I imagine) and this can make things awkward for you later on.
WPF was really designed to enable developer to use resizable controls so that the UI can resize itself when the user resizes the application. Different Panels provide different sizing abilities to their child controls and you can find out more about that from the Panels Overview page on MSDN. However, back to your question regarding the Grid class.
Because you have used the Visual Studio Designer, your controls have not ended up in the Grid cells that you wanted, instead just being placed 'on top of', or 'in front of' them. In order to place a control into a particular Grid cell, you need to set the Grid.Row and/or Grid.Column Attached Properties. See this example taken from the last linked page from MSDN:
<Grid VerticalAlignment="Top" HorizontalAlignment="Left" ShowGridLines="True" Width="250" Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock FontSize="20" FontWeight="Bold" Grid.ColumnSpan="3" Grid.Row="0">2005 Products Shipped</TextBlock>
<TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="0">Quarter 1</TextBlock>
<TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="1">Quarter 2</TextBlock>
<TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="2">Quarter 3</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="0">50000</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="1">100000</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="2">150000</TextBlock>
<TextBlock FontSize="16" FontWeight="Bold" Grid.ColumnSpan="3" Grid.Row="3">Total Units: 300000</TextBlock>
</Grid>
You appear to have placed all your BigGrid elements into a single cell of that layout grid, and the only thing stopping them from appearing on top of each other is the fact you've defined margins. You have not defined a margin for your border, but then defined margins for its children, which means they'll be offset.
Really, for best layout, you want to avoid margins as much as possible and divide your BigGrid into rows and columns. Then place your UI into those cells. If your border is within its own cell you will not have it appear to wrap everything.
I'm trying to show text in page of application in 3 textblocks. I want to scroll this because the text is dynamically changed and it depends on what we choose in previous page. When I did this like that:
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="Asystent Barmana" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Name="PageName" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<ScrollViewer Name="Scroller" HorizontalAlignment="Center" Height="auto" Margin="12,10,10,-1055" Grid.Row="1" VerticalAlignment="Top" Width="460" ManipulationMode="Control" MaxHeight="2500" >
<StackPanel HorizontalAlignment="Left" Height="auto" VerticalAlignment="Top" Width="460">
<TextBlock Name="MissingSkladnik" TextWrapping="Wrap" Height="auto" FontSize="24"/>
<TextBlock Name="Skladniki" TextWrapping="Wrap" Height="auto" FontSize="24"/>
<TextBlock Name="Przepis" TextWrapping="Wrap" Height="auto" FontSize="24"/>
</StackPanel>
</ScrollViewer>
</Grid>
and the text is not so long it work fine. But in several cases the text is longer and some of text is cut off. When I change StackPanel height to, let's say 1950, it dispaly fine, but when I have shorter text, on the end of page is a black nothing to scroll :/
Any thoughts?
PS. I apologize for my english, it's been a while since I used it ;)
Edit:
I read comments and I change stackpanel to grid. I did it like that:
<ScrollViewer Name="Scroller" HorizontalAlignment="Center" Height="auto" Margin="12,10,10,-1055" Grid.Row="1" VerticalAlignment="Top" Width="460" ManipulationMode="Control" MaxHeight="2500" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="MissingSkladnik" TextWrapping="Wrap" Height="auto" FontSize="24" Grid.Row="0"/>
<TextBlock Name="Skladniki" TextWrapping="Wrap" Height="auto" FontSize="24" Grid.Row="1"/>
<TextBlock Name="Przepis" TextWrapping="Wrap" Height="auto" FontSize="24" Grid.Row="2"/>
</Grid>
</ScrollViewer>
It doesn't work either. If I set the height of stackpanel it works, but when there is small amount of text it doesn't look nice. User can srcoll black empty screen :/
A StackPanel will not resize its content in the same way that a Canvas will not resize its content. However, a Grid control can resize its contents. Try replacing this:
<StackPanel Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="Asystent Barmana" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Name="PageName" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
with this:
<Grid Name="TitleGrid" Grid.Row="0" Margin="12,17,0,28">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="Asystent Barmana"
Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Grid.Row="1" Name="PageName" Text="page name" Margin="9,-7,0,0"
Style="{StaticResource PhoneTextTitle1Style}"/>
</Grid>
UPDATE >>>
In WPF, setting explicit Height and/or Width dimensions and/or Margins will stop a Control from sizing itself. If you want the ScrollViewer to re-size itself to the size of its content, try remove the explicit layout and dimension values that you have set, eg. Margin.
I have a listview of width set to Auto. When I run the windows app, it opens in normal size(not maximized). But when I maximize the window, the listview's width will be same and the space to its right is empty.
normal size
|_________________________|
Maximized
|_________________________|...........
even though the window is now in full screen occupied.
Please guide me in workin on this.
Thanks
Ramm
StackPanel, by design, does not care about visual space. It aims to take up the smallest amount of space possible. You can leave the innermost StackPanel that wraps the radio buttons in place, but your outer layout containers should be changed to Grid or, as in my example below, DockPanel:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="445" Width="515">
<DockPanel Name="spDataFlow" Margin="0,45,0,0" >
<DockPanel x:Name="stkPnlDataFlow" VerticalAlignment="Top">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
</Grid>
<StackPanel Grid.Row="1" Background="Red" Margin="20,15,0,0" Orientation="Horizontal" VerticalAlignment="Center" >
<RadioButton Name="rdbtnUploadData" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" Foreground="White" Content="Upload Data" IsEnabled="True" CommandParameter="UploadAll"/>
<RadioButton Name="rdbtnDownloadData" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" Foreground="White" Content="Download Data" Margin="20,0" CommandParameter="DownloadAll"/>
<RadioButton Name="rdbtnUploadSelected" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" Foreground="White" Content="Update Data" Margin="10,0" CommandParameter="UpdateSelected"/>
</StackPanel>
</DockPanel>
</DockPanel>
</Window>
Well, I believe that by default the ListView control automatically fills all available space so it is very strange that have such an issue. Could you paste your code?
I have a WPF ListBox control. It can have a long list of items.
When i am working with the normal screen resolution i.e 1024 * 768, it shows the listbox with scrollbar properly, if I mention the MinHeight and MaxHeight for the listbox.
and when I switch to another resolution, which is 1280 * 1024, ideally, the listbox should fit to the screen resolution. but, it is not happening. Due to the height, which i had mentioned, it remains the same, leaving a lot of a empty space down, which obviously does not look good.
and I need a scrollbar for normal 1024*768 resolution, so i must put MinHeight and MaxHeight.
Is there any solution, to view the extended ListBox which occupies the space properly for higher resolutions?
Thanks
Use panels to lay out your controls - don't use explicit widths and heights. For example:
<Grid>
<Grid.RowDefinitions>
<Row Height="*"/>
<Row Height="Auto"/>
</Grid.RowDefinitions>
<!-- ListBox will take up all remaining space after the Button -->
<ListBox/>
<!-- Button will take up only the space it needs -->
<Button Grid.Row="1"/>
</Grid>
<StackPanel Orientation="Horizontal" Margin="0,0,0,5" VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Row="0">
<Label FontWeight="Bold" FontSize="11" HorizontalAlignment="Left" Margin="0,0,5,5">Term:</Label>
<ComboBox x:Name="Term" Margin="0,5,5,0">
</ComboBox>
</StackPanel>
<CheckBox Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="displaySummaryCheckBox" Margin="2,2,0,5" FontSize="11" Content="Display Summary" IsChecked="True" FontWeight="Normal"></CheckBox>
</Grid>
<Grid DockPanel.Dock="Bottom">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" VerticalAlignment="Top" Margin="0,0,0,4" HorizontalAlignment="Left" FontWeight="Bold" FontSize="11">Display Columns</Label>
<ListBox Grid.Row="1" VerticalAlignment="Top" Margin="5,0,5,4" HorizontalAlignment="Left" x:Name="columnsList" Width="197" FontSize="11">
</ListBox>
<Button Grid.Row="2" Margin="5,0,5,2" HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="selectAll" Width="75" Content="Select All" FontWeight="Normal" FontSize="11" Height="23" Click="selectAll_Click"/>
</Grid>
</Grid>
</DockPanel>