Showing loading adorner and make the UI responsive in WPF - wpf

In my wpf application, I have a Usercontrol in a wpf window which is a part of another module.This parent Usercontrol is having another two child user controls in it. These two child usercontrol is loading data from two different CSV files and shows graphs on each usercontrol. When the main window loads, these two usercontrols loads data from these 2 csv files and display the graphs. But the problem is, this process is taking too much time and the window will become non responsive.
I want to have a loading adorner (like loading....please wait) on the screen and the UI will be responsive. When the 2 usercontrols loaded the graphs properly, the Loading adorner will be gone. Could any one please share the code for this ??
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center" Height="30" Width="Auto">
<TextBlock Text="Your Name " FontFamily="Verdana" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="12" FontWeight="Bold" />
<ComboBox Name="cboName" ItemsSource="{Binding GraphStringType}" Height="25" Width="300" HorizontalAlignment="Center" VerticalAlignment="Center" Focusable="False"
IsTextSearchEnabled="True" StaysOpenOnEdit="True" IsReadOnly="True" IsEditable="True" Text="-- Select your Name --">
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Width="100" Height="23" Content="{Binding}" IsChecked="{Binding IsChecked}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
<Grid Name="graphGrid" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<useCtrl:UsrCtrlGraphUI x:Name="graph1" GraphFilePath="{Binding FileNameWithPath}" Grid.Column="0" Height="Auto" Width="Auto" />
<GridSplitter HorizontalAlignment="Stretch" ResizeDirection="Columns" ResizeBehavior="PreviousAndNext"
VerticalAlignment="Stretch" Grid.Column="1" Grid.Row="1" Width="5" Background="Silver">
</GridSplitter>
<useCtrl:UsrCtrlGraphUI x:Name="graph2" GraphFilePath="{Binding FileNameWithPath}" Grid.Row="1" Grid.Column="2" Height="Auto" Width="Auto" />
</Grid>
The loading data from the 2 csv files is a very huge task and it causes non responsive UI.
How to set a loading adorner over the window and the UI becomes responsive ?

Related

fluid layout in wpf is rendering enormous controls

EDIT
Having removed the <ViewBox Stretch="UniformToFill"> from the xaml, it renders better - the size of the controls are more appropriate, however, as the Frame is empty when I'm loading the window, the whole app appears as a band across the center of my screen.
When I do load content into the frame, the rest of the window fits width to the frame, rather than to the screen resulting in empty space on the left and right of the Frame's content.
ORIGINAL QUESTION
I've never done a fluid layout before so what I've done is based entirely on what I've gleaned from answers to other questions on SO and around the interwebz.
So the following XAML, I figured, should be "responsive" which is to say that it would render much the same on every screen resolution without using fixed widths.
Unfortunately, the controls are rendering at enormous scale. What should be a 30x30 button looks to be rendering around 10x that size (see the screenshots below - the second one is the app maximized to fullscreen).
How can I change my xaml to make these controls render to the row heights and to the width of the display?
<Grid>
<Viewbox Stretch="UniformToFill">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="50"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Titlebar -->
<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal" Background="#2d2d30">
<StackPanel Name="spTitlebar1" FlowDirection="LeftToRight" Orientation="Horizontal" MouseDown="spTitlebar_MouseDown">
<Label Name="lblTitle" HorizontalAlignment="Left" BorderThickness="0" Foreground="White">IHS Towers SCADA</Label>
</StackPanel>
<StackPanel Name="spTitleBar2" FlowDirection="RightToLeft" Orientation="Horizontal" MouseDown="spTitlebar_MouseDown">
<Button Name="btnClose" Content="X" Click="btnClose_Click" Style="{StaticResource TitleButton}" />
<Button Name="btnMinimize" Content="_" Click="btnMinimize_Click" Style="{StaticResource TitleButton}" />
<Border BorderThickness="1,0,0,0" BorderBrush="#686868">
<Button Name="btnSettings" Click="btnSettings_Click" Style="{StaticResource TitleButton}" ToolTip="Settings">
<Image Source="Images/settings-icon.png" Height="20" Width="20"/>
</Button>
</Border>
<Button Name="btnReports" Click="btnReports_Click" Style="{StaticResource TitleButton}" ToolTip="View reports">
<Image Source="Images/reports-icon.png" Height="20" Width="20"/>
</Button>
</StackPanel>
</StackPanel>
<!-- Towers Bar across the top Height="50" -->
<StackPanel Grid.Row="1" Grid.Column="0" Name="spTowers" Background="#2d2d30" VerticalAlignment="Top" Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,0">
<Border BorderThickness="5,0,0,0" BorderBrush="#686868" VerticalAlignment="Top"></Border>
</StackPanel>
<!-- Alert Window in the center -->
<Frame Name="frmBody" Grid.Row="2" Grid.Column="0" Margin="0" Background="#1e1e1e" NavigationUIVisibility="Hidden" />
<!-- Actions Bar across the bottom Height="60" -->
<StackPanel Grid.Row="3" Grid.Column="0" Name="spActions" Height="60" Background="#2d2d30" VerticalAlignment="Top" FlowDirection="RightToLeft" Orientation="Horizontal">
<Button Name="btnSMS" Click="btnSMS_Click" Height="30" Width="66" Margin="10,10,10,10" Style="{StaticResource RoundedButtonGreen}">Send SMS</Button>
</StackPanel>
</Grid>
</Viewbox>
</Grid>

Border wrapping wrong element in WPF

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.

Make the last TextBox in a DataTemplate Stretch

I have an ItemsControl:
<Border Grid.Row="1" Margin="20" BorderBrush="AliceBlue" BorderThickness="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ItemsControl Margin="10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding SelectedEventHistoryEntryCollection}" ItemTemplateSelector="{StaticResource computerEventHistoryDataTemplateSelector}"/>
</Border>
With some datatemplates. I'm testing the first template:
<DataTemplate x:Key="DetailsDataTemplate">
<Grid>
<Label Width="150" HorizontalAlignment="Left" VerticalAlignment="Top" Content="{x:Static resx:Resources.Label_ServiceDept}"/>
<TextBox Margin="110,0,0,0" Width="200" IsReadOnly="True" Text="{Binding ServiceDepartment}" VerticalAlignment="Top" HorizontalAlignment="Left"/>
<Label Width="150" Margin="0,40,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Content="{x:Static resx:Resources.Label_SLA}"/>
<TextBox Margin="110,40,0,0" Width="200" IsReadOnly="True" Text="{Binding SLA}" VerticalAlignment="Top" HorizontalAlignment="Left"/>
<Label Width="150" Margin="0,80,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Content="{x:Static resx:Resources.Label_Details}"/>
<TextBox Margin="110,80,10,10" IsReadOnly="True" TextWrapping="Wrap" Text="{Binding Details}"/>
</Grid>
</DataTemplate>
I would like the last Textbox in the datatemplate to use up the remaining space, but nothing I tried works. How can I get this uncooperateive TextBox to stretch?
Edit: Removed the Height Property on the Textbox.
Change the grid to a DockPanel with LastChildFill="true".
You can then get rid of all of the Margins and let WPF do the layout automatically.
Use a <DockPanel> instead of a <Grid>.
The last item in the DockPanel uses remaining space.
Generally, I use <Grid.RowDefinitions> and <Grid.ColumnDefinitions> in conjunction with star sizing * instead of margins for this type of layout.
UPDATE 1: (Removed for clarity)
UPDATE 2: When I wind up in situations like this where I can’t figure out where to apply a binding or a template I try to back up and look at the problem differently. I almost always take it back to the MVVM pattern. In this case, your Model is your EventHistory object. Your ViewModel has an ObservableCollection<EventHistory>. And your View is simply binding to that collection. So, to get something like this:
You would use something like this for your View:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="8" />
<RowDefinition Height="1.5*" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0" AutoGenerateColumns="True"
ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True"
HorizontalGridLinesBrush="DarkGray" VerticalGridLinesBrush="DarkGray" />
<GridSplitter Grid.Row="1"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Border Grid.Row="2" BorderBrush="DarkGray" BorderThickness="1" CornerRadius="3" Padding="8">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Status" />
<TextBox Grid.Row="0" Grid.Column="1" Margin="0,0,0,8" Text="{Binding Path=Status}" />
<Label Grid.Row="1" Grid.Column="0" Content="Detailed Description" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}" />
</Grid>
</Border>
</Grid>
And that is just fine -- because that is what you are trying to achieve. The bindings on the 2 labels and textboxes at the bottom of the screen don’t have to be part of any data template. They are part of the view (everything inside the red border in the screenshot). All of the resizing works and everything is good. If you really want to move things into a DataTemplate, it is probably possible, but this seemed more natural at this point.
NOTE: After creating the View (area inside the red border) I hosted it in the main window leaving an area to the right as per your screenshot. I also took a few liberties with a grid splitter, star resizing and margins so things would take up all of the available space while maintaining the pictured proportions.
Hopefully that helps!
I was a little slow on the uptake with my first answer. After realizing what you were after I don't think that approach was correct. Also, I don't think you can easily achieve what you're after using DataTemplates. However, I do think you have a few options:
Check into Prism since is is good at doing things like building composite applications. However, it seems like WAY overkill for this problem. So, a more direct approach may be...
Build out custom controls for each separate detail view you have and then write some custom logic to load each view as needed. You would set it up like this...
You main grid and your details view host (i.e. the ContentControl) would be set up something like this:
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="8" />
<RowDefinition Height="1.5*" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0" />
<GridSplitter Grid.Row="1" Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Border Grid.Row="2" BorderBrush="DarkGray" BorderThickness="1" CornerRadius="3" Padding="8">
<ContentControl Grid.Row="2" x:Name="myContent" />
</Border>
</Grid>
And each of your custom controls for your individual detail views would be set up something like this:
<UserControl x:Class="WpfApplication1.CustomUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Status" />
<Label Grid.Row="1" Grid.Column="0" Content="Description" />
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Status}" />
<TextBox Grid.Row="1" Grid.Column="1" TextWrapping="Wrap" Text="{Binding Description}" />
</Grid>
</UserControl>
At run time a row is selected in your DataGrid, you would have to load the correct user control with some code like this:
myContent.Content = new CustomUserControl();
Each of your custom controls would have to use star sizing, etc. to get the layouts to look right - which is what you were after with your question. Obviously there is still a lot of wireup that would need to be done.
That should give you what you are after. Sorry for the run-around on the first answer!

WPF - Usercontrol height does not size properly

I have an issue I cannot figure out. I hope I can explain things enough.
Basically, I have a usercontrol that I'm looking to use as a sort of in window modal dialog.
<Grid>
<Rectangle Opacity=".75" Fill="White"/>
<Border Width="425" BorderBrush="LightGray" BorderThickness="2" CornerRadius="20,0,20,0" Padding="3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="15"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<!-- First Name -->
<Label Grid.Row="0" Grid.Column="0" Content="First Name:"/>
<TextBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding FirstName}" Margin="3"/>
<!-- Last Name -->
<Label Grid.Row="0" Grid.Column="3" Content="Last Name:"/>
<TextBox Grid.Row="0" Grid.Column="4" Grid.ColumnSpan="2" Text="{Binding LastName}" Margin="3"/>
<!-- Address -->
<Label Grid.Row="1" Grid.Column="0" Content="Address:"/>
<TextBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" Text="{Binding Address}" HorizontalAlignment="Stretch" Margin="3"/>
<!-- City -->
<Label Grid.Row="2" Grid.Column="0" Content="City:"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding City}" Margin="3"/>
<!-- State -->
<Label Grid.Row="2" Grid.Column="2" Content="State:"/>
<ComboBox Grid.Row="2" Grid.Column="3" ItemsSource="{Binding States}" SelectedValue="{Binding State}" Margin="3"/>
<!-- Zip Code -->
<Label Grid.Row="2" Grid.Column="4" Content="Zip Code:"/>
<TextBox Grid.Row="2" Grid.Column="5" Text="{Binding ZipCode}" Margin="3"/>
<Button Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="6" Width="100" HorizontalAlignment="Center" Content="Save" Command="{Binding SaveCustomerCommand}"/>
</Grid>
</Border>
</Grid>
I also have a resourcedictionary containing a datatemplate to connect this usercontrol to it's viewmodel.
<DataTemplate DataType="{x:Type vm:CreateCustomerViewModel}">
<view:CreateCustomerView/>
</DataTemplate>
Finally, in the main window viewmodel, I create an instance of the control's viewmodel, and in the main window view, I am using an itemscontrol and binding it's itemssource property to the instance of the control's viewmodel.
<ItemsControl Height="600" Grid.Row="0" ItemsSource="{Binding CreateCustomerViewModel}" Grid.RowSpan="2" />
Now, my issue is using the itemscontrol in the main window, I've tried a few different ways, but I cannot get the control to be the height of the window. I'm not sure if I shouldn't be using an itemscontrol, or what I'm doing wrong. Any help is very much appreciated.
ItemsControl is for collections. By default it uses a StackPanel to contain its child elements, which disallows stretching in the stack direction (Vertical by default). For a single item use ContentControl (the base of things like Button and Label) instead:
<ContentControl Height="600" Grid.Row="0" Content="{Binding CreateCustomerViewModel}" Grid.RowSpan="2" />
You could try the following:
Put your ItemsControl in a Grid.
Declare your ItemsControl with VerticalContentAlignment="Stretch".
It shouldn't make any difference because it's the default setting, but declare your ItemsControl with VerticalAlignment="Stretch" and try removing the Height="600".

WPF - Resizing Columns and Rows in a Grid

Ok, I'm using the grid to list various content. How can I get specific colums to resize while others stay fixed.
That is, form pops up with specifc Initial column sizes for the controls... if the user RESIZES the form... i want certain 'memo' like fields to expand. How to do that? i seem to only be able to get ALL 'second' columns to expand in height... not just 1 (last one)... or specific ones.
Thanks for any help!!
Here is the layout... how can i make the 'long' text resizeable with form resize, and keep the button glued to the bottom of the form??? tx
<DockPanel VerticalAlignment="Top">
<Grid DockPanel.Dock="Top" VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="0" Margin="10,10,10,10" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition MinWidth="150" ></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition MinHeight="80" Height="Auto"></RowDefinition>
<RowDefinition ></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Test1"/>
<Label Grid.Column="0" Grid.Row="1" Content="Test2 -Long notes"/>
<Label Grid.Column="0" Grid.Row="2" Content="Test3"/>
<TextBox Height="Auto" Grid.Column="1" Grid.Row="0" />
<TextBox Height="Auto" Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" />
<TextBox Height="Auto" Grid.Column="1" Grid.Row="2" />
</Grid>
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right" MinHeight="20" Margin=" 0,0,10,10">
<Button Content="OK" Margin="0,0,10,0" Width="75" IsDefault="True"/>
<Button Content="Cancel" Width="75" IsCancel="True" />
</StackPanel>
</DockPanel>
(added after 1st 'answer')
Now, if i remove the bottom stackpanel (Ok, Cancel buttons) out of equation to make this easier and i set the 1st and 2nd rows to a fixed value... i seem to be able to get this working (don't want to have to set a max height though) ... oh and i need to change the verticalAlignment to 'stretch'. But as soon as i add the StackPanel for the buttons again... the stretching no longer works... so here is the next revised version...
<DockPanel VerticalAlignment="Stretch">
<Grid DockPanel.Dock="top" VerticalAlignment="Stretch" Grid.Column="0" Margin="10,10,10,10" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition MinWidth="150" Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition MaxHeight="30"></RowDefinition>
<RowDefinition MinHeight="80" Height="*"></RowDefinition>
<RowDefinition MaxHeight="30"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Test1"/>
<Label Grid.Column="0" Grid.Row="1" Content="Test2 -Long notes"/>
<Label Grid.Column="0" Grid.Row="2" Content="Test3"/>
<TextBox Grid.Column="1" Grid.Row="0" />
<TextBox Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" />
<TextBox Grid.Column="1" Grid.Row="2" />
</Grid>
<StackPanel DockPanel.Dock="Bottom" VerticalAlignment="Bottom" HorizontalAlignment="Right" Orientation="Horizontal" MinHeight="20" Margin=" 0,0,10,10">
<Button Content="OK" Margin="0,0,10,0" Width="75" IsDefault="True"/>
<Button Content="Cancel" Width="75" IsCancel="True" />
</StackPanel>
</DockPanel>
So I'm still having problems...
Use * for the column width instead of Auto, which tells the column to take up whatever space is left after the other columns are set.
If you need multiple columns to share the available space in different percentages, you can prefix the * with a number, as in "2*" and "3*". By default, "" means 1.
HTH,
Berryl
I seem to only be able to solve the problems by incorporting the StackPanel in its own grid row, and column. Here is my solution. Not sure if dock panel is necessary in this case... but without tinkering more ... that's my current solution. If any one can explain to me how to get it working with the stack panel OK, Cancel buttons 'outside' the grid, i'd love to know. Meanwhile, this solution is available for those of you looking into this sort of problem. As you see you need to use Auto in all the other row definitions. * where u want it to expand.
<DockPanel VerticalAlignment="Stretch">
<Grid DockPanel.Dock="top" VerticalAlignment="Stretch" Grid.Column="0" Margin="10,10,10,10" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition MinWidth="150" Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition MinHeight="80" Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Test1"/>
<Label Grid.Column="0" Grid.Row="1" Content="Test2 -Long notes"/>
<Label Grid.Column="0" Grid.Row="2" Content="Test3"/>
<TextBox Grid.Column="1" Grid.Row="0" />
<TextBox Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" />
<TextBox Grid.Column="1" Grid.Row="2" />
<StackPanel Grid.Column="1" Grid.Row="3" VerticalAlignment="Bottom" HorizontalAlignment="Right" Orientation="Horizontal" MinHeight="20" Margin=" 0,10,0,0">
<Button Content="OK" Margin="0,0,10,0" Width="75" IsDefault="True"/>
<Button Content="Cancel" Width="75" IsCancel="True" />
</StackPanel>
</Grid>
</DockPanel>
If you want to be able to re-size only one of the squares made by the Row and Column Definitions you should add a Grid or whichever container element inside of one the squares. Then you'll make the Grid inside the square re-size accordingly. This way all the Definitions won't re-size, instead the grid and it's elements inside will re-size and thus not changing the other elements. It's not common but you can have as many stack panels and grids and set their visibility when needed. Sometimes when something doesn't work stick them inside something else and experiment with it. You might just get it by accident, but you'll still get it.

Resources