Reputation: 151
I am having trouble sizing a WPF control (I'll use the Grid
control in this example) to the size of the Client
area of a Window
. I realize that the Grid
automatically fills all available space by default, however I require the Grid
's Width
to be set manually so that I may bind to it from another control (a DataGrid with one of its column's Width
's set to Star
if it makes any difference).
Please consider the following XAML:
<Window x:Class="TestApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="768" Width="1024"
x:Name="mainWindow">
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Auto">
<Grid x:Name="testGrid" Background="DarkGray">
</Grid>
</ScrollViewer>
</Window>
And the following Code-Behind:
using System.Windows;
namespace TestApplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
testGrid.Width = mainWindow.Width - (SystemParameters.BorderWidth * 2);
}
}
}
When running this simple application, the Grid
has a width that is slightly larger than the Client
area of the Window
, resulting in a Horizontal Scroll Bar
being displayed. If SystemParameters.BorderWidth
does not accurately calculate the width of the Window
's border, what does?
As per the most recent MSDN documentation, SystemParameters.BorderWidth
: Gets the metric that determines the border width of the nonclient area of a nonminimized window.
Upvotes: 3
Views: 1701
Reputation: 151
After having fought with this sizing issue for quite some time, I have finally found an elegant solution to the problem. Though I have alread selected @Rick Sladkey's response as the answer (and answer my question it did), I thought I might post my updated understanding in hopes that it might help someone else down the line.
The real frustration point, it turns out, was in dealing with the ScrollViewer
. While sizing my content to the ActualWidth
of the ScrollViewer
worked wonderfully when it's VerticalScrollBar
was not visible, things began to break down as soon as my content grew to a vertically scrollable height. Though I had expected the binding on ActualWidth
to resize my contol to fit within the viewable area of the ScrollViewer
, in reality it remained the same width and became horizontally scrollable as well.
As it turns out, the fix was actually quite simple. Rather than binding the height or width of a control to the ActualHeight
or ActualWidth
of the ScrollViewer
(respectively), bind the height or width of the control to the ViewportHeight
or ViewportWidth
of the ScrollViewer
.
Upvotes: 1
Reputation: 34250
Here is one way of binding the size of the client width with no code-behind:
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Auto">
<Grid x:Name="testGrid" Background="DarkGray" Width="{Binding Content.ActualWidth, ElementName=mainWindow}">
</Grid>
</ScrollViewer>
This uses your named top-level Window
and gets with actual width of it's content, a ScrollViewer
in this case. If for some reason you want to want the content of the window to be a different size than the window you can enclose it in an empty Grid
so this technique still works.
Upvotes: 5
Reputation: 5008
Instead of setting the width manually, how about binding to the grid's ActualWidth
property instead (this will give you an actual value)
Upvotes: -1