Cannot get TextBoxes(2) to fill grid space - wpf

So I'm convinced that this is probably an easy answer and I'm just not seeing it, but after 20 google searches and 3 days of trying to figure it out on my own, I surrender. The xaml I'm using is below. What I need is for the two textboxes to fill all remaining space and to be equally sized. I've tried StackPanel, DockPanel, Grid (as it is below), and even nesting each of these and nesting a UniformGrid. Nothing seems to work, I just get 2 textboxes with whatever height I specify for MinHeight. Changing the Grid.Row setting from Auto to * just results in the TextBoxes centering themselves and moving as the window shrinks and grows.
<TabItem Header="Notes" Name="notesTab">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="23"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="Select Contact:" Height="28" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" FontStyle="Italic" FontWeight="Bold"></Label>
<ComboBox Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Right" Width="150" ItemsSource="{Binding Source={StaticResource contactList}}" DataContext="{Binding Source={StaticResource contactList}}" Name="contactSelectionBox"></ComboBox>
<WrapPanel Grid.Row="1" Height="Auto" Grid.ColumnSpan="2" Margin="5">
<WrapPanel.Width>
<Binding ElementName="callNotes" Path="ActualWidth" />
</WrapPanel.Width>
<Label Content="TAD" Width="Auto" Name="tadShortcut" MouseLeftButtonDown="tadShortcut_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="VI" Width="Auto" Name="verifyInfoShortcut" MouseLeftButtonDown="verifyInfoShortcut_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="Not there" Width="Auto" Name="uipShortcut" MouseLeftButtonDown="uipShortcut_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="WUSP" Width="Auto" Name="wuspShortcut" MouseLeftButtonDown="wuspShortcut_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="FNYD" Width="Auto" Name="fnydShortcut" MouseLeftButtonDown="fnydShortcut_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="Not Employed" Width="Auto" Name="notEmployedShortcut" MouseLeftButtonDown="notEmployedShortcut_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="Message" Width="Auto" Name="messageShortcut" MouseLeftButtonDown="messageShortcut_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="Late Fees" Width="Auto" Name="lateFeesShortcut" MouseLeftButtonDown="lateFeesShortcut_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="Payoff" Width="Auto" Name="payoffReqShortcut" MouseLeftButtonDown="payoffReqShortcut_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="No Commit" Width="Auto" Name="noCommit" MouseLeftButtonDown="noCommit_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="12/12" Width="Auto" Name="twelve12" MouseLeftButtonDown="twelve12_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="No ID" Width="Auto" Name="vmNoID" MouseLeftButtonDown="vmNoID_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="Wrong #" Width="Auto" Name="wrongNumber" MouseLeftButtonDown="wrongNumber_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="Day Off" Width="Auto" Name="dayOff" MouseLeftButtonDown="dayOff_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="FPD" Width="Auto" Name="firstPaymentDefault" MouseLeftButtonDown="firstPaymentDefault_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="Repo Pmnt" Width="Auto" Name="repoPayment" MouseLeftButtonDown="repoPayment_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="CS Xfer" Width="Auto" Name="custServ" MouseLeftButtonDown="custServ_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
<Label Content="Spanish" Width="Auto" Name="spanish" MouseLeftButtonDown="spanish_MouseLeftButtonDown" MouseEnter="notesLabel_MouseEnter" MouseLeave="notesLabel_MouseLeave" />
</WrapPanel>
<MyNamespace:WatermarkTextBox Grid.Row="2" Grid.ColumnSpan="2" Style="{StaticResource TextBox Style}" MinHeight="98" Margin="15,5,15,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Name="callTwoNotes" TextChanged="callTwoNotes_TextChanged" FontWeight="Bold" IsEnabled="False" ClipToBounds="False"></MyNamespace:WatermarkTextBox>
<Button Grid.Row="3" Grid.ColumnSpan="2" Height="23" Name="flipFlopButton" VerticalAlignment="Center" Width="75" Click="flipFlopButton_Click">
<Image Source="Images/FlipFlop.gif" />
</Button>
<MyNamespace:WatermarkTextBox Grid.Row="4" Grid.ColumnSpan="2" Style="{StaticResource TextBox Style}" MinHeight="98" Margin="15,5,15,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Name="callNotes" TextChanged="callNotes_TextChanged" FontWeight="Bold"></MyNamespace:WatermarkTextBox>
</Grid>
</TabItem>
The xaml for the style on the TextBoxes is below, just for completeness.
<Style x:Key="TextBox Style" TargetType="{x:Type MyNamespace:WatermarkTextBox}">
<Setter Property="CharacterCasing" Value="Upper" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Height" Value="23" />
<Setter Property="Width" Value="Auto" />
<Setter Property="SelectAllOnGotFocus" Value="True" />
</Style>

There are two issues with the code posted
The Grid's RowDefintion for the TextBoxes is listed as Auto instead of *. This means the Row will be sized based on the size of the cell contents, not based on the Grid's size. Change this to * so it's size will be based on available space.
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="23"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
The other problem is your TextBox style is defining a Height for your item. This means it will keep the TextBox at the specified Height and not re-size it to fit the available space. You can either remove this style setter, or set the Height on your TextBoxes in the Grid to Auto.
Remove this setter
<Style x:Key="TextBox Style" TargetType="{x:Type MyNamespace:WatermarkTextBox}">
<Setter Property="Height" Value="23" />
...
</Style>
Or set the Height property on your TextBox tag to Auto. Setting the property in the object's tag will overwrite a styled property
<MyNamespace:WatermarkTextBox Height="Auto" Grid.Row="2" ... />
<MyNamespace:WatermarkTextBox Height="Auto" Grid.Row="4" ... />

This was answered a few minutes ago by someone else but now the answer it gone. Try deleting these lines:
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
As might be overwriting the Stretch

Edit: Ok i tried your code and what you need to change is your Grid RowDefinitions, try
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="23"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
and you might want to remove your minheight aswell. In fact, you should try to remove all you explicit heights and widths, let WPF take care of that, thats what the layout system is for.

Related

Enable Button if One of Three Textboxes across 3 tabs has content

I have a Button that lives outside a tab control element. Each Tab on the TabControl has either a text box for manual text entry or a search tool to look up something from a database (the value of which will also be written to the label in tab 2 & 3).
I want to enable the Print button if the textbox has content or a variable that is populated from a database query on the selected tab has content.
What would be the best way to do this, given a button can only be bound to one source? I pondered having a staging variable, but then that would also be only bound to one element.
Any ideas? I'm really new to data-binding and I'm struggling to get my head around some of the concepts.
It doesn't help that the back-end is in VB because i'm porting a number of WinForms apps to WPF and I want to do them properly.
Quick XAML:
<Window x:Name="Main1" x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" SizeToContent="Height">
<Grid>
<StackPanel >
<Grid x:Name="Activity" Margin="5,5,5,0" >
<StackPanel>
<TabControl x:Name="Main_Tabs" Background="{x:Null}" BorderBrush="Gainsboro">
<TabItem x:Name="T1" Header="H1" >
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="80*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right">Address:</Label>
<TextBox x:Name="Single_Address"
Margin="5,3"
SpellCheck.IsEnabled="True"
IsManipulationEnabled="True"
TextWrapping="Wrap"
AcceptsReturn="True"
VerticalScrollBarVisibility="Auto"
Grid.Column="1" Grid.Row="2"
Language="en-GB" Height="80">
</TextBox>
</Grid>
</TabItem>
<TabItem x:Name="T2" Header="H2" >
<Grid Grid.ColumnSpan="2" Grid.Row="1" x:Name="Grid_Elucid_Label2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="80*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right">Address:</Label>
<Label x:Name="Elucid_Address"
Margin="5,3"
Grid.Column="1" Grid.Row="2" Height="80">
</Label>
</Grid>
</TabItem>
<TabItem x:Name="T3" Header="H3">
<Grid x:Name="Grid_Sage_Label" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="80*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right">Address:</Label>
<Label x:Name="Sage_Address" Margin="5,3" Grid.Column="1" Grid.Row="2" Height="80">
</Label>
</Grid>
</TabItem>
</TabControl>
</StackPanel>
</Grid>
<Button x:Name="Print_Button" Content="Print" Padding="10" Background="{x:Null}" BorderBrush="Gainsboro" />
</StackPanel>
</Grid>
</Window>
#1 VM with few textproperties to evaluate
if you have just a few text properties and use a VM, you can go with some triggers.
I wrote this by hand so I'm sorry if the syntax isn't a 100% match.
<button content="print">
<button.style>
<style targettype={x:type button}>
<style.triggers>
<multidatatrigger>
<multidatatrigger.conditions>
<condition Binding="{Binding VMprop1}" Value="">
<condition Binding="{Binding VMprop2}" Value="">
<condition Binding="{Binding VMprop3}" Value="">
</multidatatrigger.conditions>
<multidatatrigger.setters>
<setter property="IsEnabled" value="false"/>
</multidatatrigger.setters>
</multidatatrigger>
</style.triggers>
</style>
</button.style>
<button>
2 no VM or a lot of properties to evaluate
bind to the TextChanged of all TextBoxes and evaluate their state, and set the IsEnabled from your button (if you want use a Dependency Property)
<button x:Name="btn1" content="print" IsEnabled="{Binding CanPrint}"/>
<textbox x:Name="tb1" TextChanged="EvaluateCanPrint"/>
<textbox x:Name="tb2" TextChanged="EvaluateCanPrint"/>
<textbox x:Name="tb3" TextChanged="EvaluateCanPrint"/>
<textbox x:Name="tb4" TextChanged="EvaluateCanPrint"/>
...
private void EvaluateCanPrint() {
// ViewModel.EvaluateCanPrint();
ViewModel.CanPrint =
!string.isNullOrEmpty(tb1.Text) &&
!string.isNullOrEmpty(tb2.Text) &&
...;
}
// Original answer
//private void EvaluateTextChanged() {
// if (string.isNullOrEmpty(tb1.Text) &&
// string.isNullOrEmpty(tb2.Text) &&
// ...)
// {
// btn1.IsEnabled = false;
// }
//}

Why doesn't the ScrollViewer limit vertical expansion?

I've been working with WPF for several years, now, yet the layout mechanism often makes me feel like a noob (and maybe I still am). My page is fairly complex. Below, I've eliminated much of the unrelated content, but left the general structure of the page in tact. I have two ItemsControls. Both have ScrollViewers. They both used to have the ScrollViewrs wrapping the <ItemsPresenter />. A post I saw had me try moving the first one to wrap the entire ItemsControl to see if that fixed my issue. It did not.
The main differences between the ItemsControls is that the first has a series of DataTemplates for the content, where the second defines the content inline.
Everything displays properly with the exception that the first one forces its Grid cell to expand to accommodate all content, rather than enabling the vertical scroll bar. The second instance, properly activates the ScrollViewer when the content is to long.
What am I missing? (Hopefully something stupid I just missed.)
Here's my XAML:
<vsupport:CBUserControlBase x:Class="CB.WPFClient.Views.BillingMasterView" ... >
<vsupport:CBUserControlBase.Resources>
<Storyboard>
<ThicknessAnimation />
</Storyboard>
<Storyboard>
<ThicknessAnimation />
</Storyboard>
</vsupport:CBUserControlBase.Resources>
<Grid Margin="1" IsEnabled="{Binding Path=IsBusy, Converter={StaticResource BoolInverse}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<local:FirmSelectorView Grid.Row="0" Margin="1,1,1,1"/>
<Grid Grid.Row="1" ClipToBounds="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Margin="1,0,0,0">
<!-- Unrelated Content -->
</Grid>
<Grid Grid.Column="1" Margin="1,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="White">
<!-- Unrelated Content -->
</Grid>
<Grid Grid.Row="1" Margin="0,1,0,0">
<!-- Unrelated Content -->
</Grid>
<Grid Grid.Row="2" Margin="0,1,0,0">
<!-- Unrelated Content -->
</Grid>
<Grid Grid.Row="3" Margin="0,1,0,0">
<!-- Unrelated Content -->
</Grid>
<!-- Notes and Related Entities -->
<Grid Grid.Row="4" Margin="0,1,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<!-- Unrelated Content -->
</Grid>
<!-- Related Entities -->
<Grid Grid.Column="1" Margin="1,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Grid.Column="0" Background="{StaticResource brush_Logo}" Foreground="White" Padding="5,0,0,0" Height="24"
HorizontalContentAlignment="Left" VerticalContentAlignment="Center"
Content="Related Entities" />
<!-- This one expands when multiple content items are longer than vertical space. -->
<!-- Scroll viewer used to be inside ItemsControl. Tried moving it to see if that helped. -->
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Hidden">
<ItemsControl ItemsSource="{Binding Path=RelatedEntities}" x:Name="RelatedEntitiesItemsControl">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type models:C}">
<Grid Margin="2,2,2,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" CornerRadius="5,0,0,5" Padding="0,2,0,2">
<TextBlock Foreground="White" FontSize="10" Background="Transparent">
</TextBlock>
</Border>
<Border Grid.Column="1" Background="#FFF5F7FF" CornerRadius="0,5,5,0" Margin="3,0,0,0">
<Grid>
</Grid>
</Border>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type models:P}">
<Grid Margin="2,2,2,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" CornerRadius="5,0,0,5" Padding="0,2,0,2" Background="{StaticResource brush_Plan}">
<TextBlock Foreground="White" FontSize="10" Background="Transparent">
</TextBlock>
</Border>
<Border Grid.Column="1" Background="#FFF5F7FF" CornerRadius="0,5,5,0" Margin="3,0,0,0">
<Grid>
</Grid>
</Border>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type models:A}">
<Grid Margin="2,2,2,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" CornerRadius="5,0,0,5" Padding="0,2,0,2" Background="{StaticResource brush_Account}">
<TextBlock Foreground="White" FontSize="10" Background="Transparent">
</TextBlock>
</Border>
<Border Grid.Column="1" Background="#FFF5F7FF" CornerRadius="0,5,5,0" Margin="3,0,0,0">
<Grid>
</Grid>
</Border>
</Grid>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.Template>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<!-- Old ScrollViewer Location -->
<ItemsPresenter />
<!-- Old ScrollViewer Location -->
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</ScrollViewer>
</Grid>
</Grid>
</Grid>
<ContentControl Grid.Row="1">
</ContentControl>
<Grid Grid.Row="2" Margin="0,1,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
</Grid>
<Grid Grid.Column="1" Margin="1,0,0,0">
</Grid>
<!-- This one works properly -->
<Grid Grid.Column="2" Margin="1,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
</Grid>
<ItemsControl Grid.Row="1" AlternationCount="2" ItemsSource="{Binding Path=Stuff}">
<ItemsControl.Template>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,1,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label />
<Label />
</Grid>
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="WhiteSmoke" TargetName="StaticTextLabel" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="{StaticResource brush_LogoLight}" TargetName="StaticTextLabel" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Grid>
<Grid Grid.Row="3" Margin="0,1,0,0">
</Grid>
</Grid>
</Grid>
</Grid>
</vsupport:CBUserControlBase>
Just a tip....you'll have a bit better luck getting answers in future by providing a proper MCVE. In this particular case your issue can be boiled down to this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Hidden">
<ItemsControl>
<ItemsControl.ItemsSource>
<x:Array Type="{x:Type sys:String}">
<sys:String>Hello World</sys:String>
<sys:String>Goodbye World</sys:String>
<sys:String>Hello World</sys:String>
<sys:String>Goodbye World</sys:String>
<!-- ... etc ... -->
<sys:String>Hello World</sys:String>
<sys:String>Goodbye World</sys:String>
</x:Array>
</ItemsControl.ItemsSource>
</ItemsControl>
</ScrollViewer>
</Grid>
When you do Height="Auto" in your row definition you're basically saying "give the controls on this row as much space as they need, which ScrollViewer promptly does irrespective of how much space its parent has. When you use Auto in conjunction with more than one row you're effectively telling the layout manager that you are expecting the first row to never exceed the amount of available space...otherwise, why would you declare another row beneath it?
The reason WPF layout is tricky is because it's different to most other layouts. Most things start at the top and work their way down, figuring out how much space to allocate based on how much is available. WPF starts by asking each control how much it wants, and then works it's way up. Once it gets to the top THEN it walks back down assigning actual sizes. So in your case you've got this ScrollViewer asking for more space than is actually available, but it's inside about 7 or 8 layers of nested Grid panels. At each level while walking up the tree the layout manager is looking at these saying "how should I split the available space amongst this Grid's children?", and each one of these is specifying "Auto" for the row in question, which is effectively saying "give this particular row as much as it wants, even if it's more than I have to offer".
I know this probably isn't what you want to hear but my suggestion would be to throw the whole layout out and start again. RowSpan and ColumnSpan are absolutely key in layouts like this, if you start using them then you'll find you can collapse the entire thing down to just a few nested layers, and you won't have ScrollViewer problems like the one above. If that's not an option then you're going to have to walk up the visual tree yourself changing each RowDefinition from Auto to something else that better meets your actual GUI requirements.

Rounded Corners in UserControl showing inner square border

I have a WPF app.
It has a grid that fills the whole page and there are 3 rows.
In the middle row I display a usercontrol depending on what menu button the User has chosen.
I want to create a rounded border around each Usercontrol and after Googling I found an example and implemented it.
It works but I get and inner rectangular border as well as the rounded outer border.
This is the markup inside my UserControl:
<Border BorderThickness="3" BorderBrush="White" CornerRadius="10" Padding="2"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid>
<Grid Background="White" >
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="220" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="1" Content="Search for Customer" />
<Label Grid.Row="1" Grid.Column="1" Content="Enter Customer First Name"/>
<Label Grid.Row="3" Grid.Column="1" Content="Enter Customer Last Name" />
<TextBox Name="txtForeName" Grid.Column="1" Grid.Row="2" />
<TextBox Name="txtSurname" Grid.Column="1" Grid.Row="4" />
<Button Name="btnCustomerSearch" Grid.Column="1" Grid.Row="5" />
</Grid>
</Grid>
</Border>
and it gives me this appearance:
The inner rectangular border is not a border at all. You have the border (white) and the grid (white as well) inside it. The grid fits your border, but area between them doesn't have any color, so it is transparent, thus you see it blue. If you want the whole area white, set the border's background white. Also, in your code one of the nested grids looks redundant.
Edit: Looks like after setting the border's background you still have two border's lines. Just remove BorderThickness and BorderBrush (It's the same as set them default) and increase padding a little. Also, you don't need to set the background of the grid separately, it's already white from the border.
This is how I imagine it:
<Border CornerRadius="10" Padding="5" Background="White"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="220" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="1" Content="Search for Customer" />
<Label Grid.Row="1" Grid.Column="1" Content="Enter Customer First Name"/>
<Label Grid.Row="3" Grid.Column="1" Content="Enter Customer Last Name" />
<TextBox Name="txtForeName" Grid.Column="1" Grid.Row="2" />
<TextBox Name="txtSurname" Grid.Column="1" Grid.Row="4" />
<Button Name="btnCustomerSearch" Grid.Column="1" Grid.Row="5" />
</Grid>
</Border>
I have changed the Border placement, and set its margin to -3.
Setting the Border background to White will still keep 4 corners of the Grid remaining Visible.
See if this works for you.
<Grid Canvas.Left="40" Canvas.Top="103">
<Grid Background="White">
<Grid Margin="5">
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="220" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="1" Content="Search for Customer" />
<Label Grid.Row="1" Grid.Column="1" Content="Enter Customer First Name"/>
<Label Grid.Row="3" Grid.Column="1" Content="Enter Customer Last Name" />
<TextBox Name="txtForeName" Grid.Column="1" Grid.Row="2" />
<TextBox Name="txtSurname" Grid.Column="1" Grid.Row="4" />
<Button Name="btnCustomerSearch" Grid.Column="1" Grid.Row="5" Content="Press" />
</Grid>
</Grid>
</Grid>
<Border BorderThickness="3" BorderBrush="White" CornerRadius="10" Padding="2" Margin="-3"/>
</Grid>

How to use Data Trigger to Conditionally format a text block

I need to conditionally change a TextBlock binding based on the value of an object which is one of many in an OC in my ViewModel. Im sure I need to use DataTriggers to accomplish this. Specifically I want to dynamically change the property that the first TexBlock below binds to for its Text Property. The OC Summary contains a collection of Name objects and each object has a Property called NameType. If NameType = 1 I want to bind to Name1, NameType=2 bind to Name2 etc. The second TextBlock is fine the way it is as it shows an associated value.
<ItemsControl Grid.Row="1" ItemsSource="{Binding Summary}" Margin="0,3,0,0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource TooltipLeftColumnTextStyle}" Text="{Binding Name}" />
<TextBlock Style="{StaticResource TooltipRightColumnTextStyle}" Text="{Binding Value}" />
<Border Grid.Row="1" Style="{StaticResource TooltipSeparatorBorder}" />
<Border Grid.Row="2" Style="{StaticResource TooltipSeparatorAlternateBorder}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Something like this might work for you:
<ItemsControl Grid.Row="1" ItemsSource="{Binding Summary}" Margin="0,3,0,0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="TheTextBlock" Style="{StaticResource TooltipLeftColumnTextStyle}" Text="{Binding Name}" />
<TextBlock Style="{StaticResource TooltipRightColumnTextStyle}" Text="{Binding Value}" />
<Border Grid.Row="1" Style="{StaticResource TooltipSeparatorBorder}" />
<Border Grid.Row="2" Style="{StaticResource TooltipSeparatorAlternateBorder}" />
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding NameType}" Value="1">
<Setter TargetName="TheTextBlock" Property="Text" Value="{Binding Name1}"/>
</DataTrigger>
<DataTrigger Binding="{Binding NameType}" Value="2">
<Setter TargetName="TheTextBlock" Property="Text" Value="{Binding Name2}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Otherwise, the other option is to control the value of the bound Name in the ViewModel so that Name returns the value you want. When NameType changes, you would raise the PropertyChanged event with the parameter "Name" on the view model so that the UI becomes aware of the text change.
What you are looking for is a DataTemplateSelector, this will allow you to swap out the template based on the value of the object (or a property on that object) that is being passed in.
There are lots of better examples on the web than I can give here but this should get you started..
http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector
http://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector.aspx
http://breakingdotnet.blogspot.co.uk/2012/05/data-template-selector-in-xaml.html

WPF combobox items list/context menu rendered behind parent

If the ItemSource property of a combo box has been set, why could clicking on the drop down botton of a combobox not display the list of available items? This may be related but within the same control, any context menu is displayed behind the user control:
The XAML for this control is as follows:
<Border Name="Border" Padding="5">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ScrollViewer.Resources>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Padding" Value="8,0,0,0"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</ScrollViewer.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Margin="5,4,0,4" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition SharedSizeGroup="labelColumn1" />
<ColumnDefinition SharedSizeGroup="labelColumn2" />
<ColumnDefinition SharedSizeGroup="dataEntryColumn" />
<ColumnDefinition Width="30"/>
<ColumnDefinition SharedSizeGroup="labelColumn2"/>
<ColumnDefinition SharedSizeGroup="dataEntryColumn" />
<ColumnDefinition MaxWidth="0" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition MinHeight="23" />
<RowDefinition MinHeight="23" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="Geometry Type" VerticalAlignment="Center" Grid.Column="1" Grid.Row="0"/>
<ComboBox Grid.Column="3" Margin="6,1,0,1" Grid.Row="0" Width="150"
Name="cmboGeometryTypes"
SelectedItem="{Binding GeometryType, Mode=TwoWay}"
HorizontalAlignment="Left"
DisplayMemberPath="Name"
Grid.ColumnSpan="1"
/>
<TextBlock Text="Symbol Type"
Grid.Column="1" Grid.Row="1" VerticalAlignment="Center"/>
<ComboBox
Name="cmboSymbolEditors"
SelectedItem="{Binding SymbolEditorViewModel, Mode=TwoWay}"
HorizontalAlignment="Left"
DisplayMemberPath="Alias"
Width="150"
Grid.Column="3"
Margin="6,1,0,1"
Grid.Row="1"
Grid.ColumnSpan="1" />
</Grid>
<Label Padding="10,0,0,0" Margin="10,0,0,3" Style="{StaticResource fadingLabelSeperatorStlye}" Grid.Row="1">
Editor
</Label>
<local:SymbologyEditorControl x:Name="editor" Grid.Row="2"/>
</Grid>
</ScrollViewer>
</Border>
and the effect I am observing is illustrated below
How do I fix this?
There was a common WPF bug that caused this behavior of any Popup type UI displaying in back instead of topmost so that may be what you're seeing. I haven't seen the issue in a while but I'm not sure if it was fixed or not. It's related to bad video drivers so you might see it only on certain machines and not all the time.
There was a hotfix available from MS support but it might be easier to just switch your application to use software rendering instead.

Resources