Set height and width of controls wihtin window size wpf - wpf

I have a following xaml file
<Window x:Class="NodeXL_Graph_Drawer.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
xmlns:controls="clr-namespace:Technewlogic.Samples.WpfModalDialog"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="NodeXL Graph" xmlns:my="clr-namespace:Smrf.NodeXL.Visualization.Wpf;assembly=Smrf.NodeXL.Control.Wpf" Loaded="Window_Loaded">
<Grid>
<Grid x:Name="ModalDialogParent" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" x:Name="col1"/>
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" >
<my:NodeXLControl Name="nodeXLControl1" HorizontalAlignment="Left" EdgeSelectedColor="Red" VertexSelectedColor="Red" ShowVertexToolTips="True" VertexClick="nodeXLControl1_VertexClick" SelectionChanged="nodeXLControl1_SelectionChanged" MouseMode="Select" MouseAlsoSelectsIncidentEdges="False" ContextMenuOpening="nodeXLControl1_ContextMenuOpening" GraphLaidOut="nodeXLControl1_GraphLaidOut">
</my:NodeXLControl>
</StackPanel>
<!--<ComboBox Height="23" Margin="39,12,119,0" Name="comboBox1" VerticalAlignment="Top" SelectionChanged="comboBox1_SelectionChanged" />-->
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch"/>
<StackPanel Grid.Column="2">
<toolkit:DataGrid AutoGenerateColumns="True" Margin="0,62,0,0" Name="grdGraphDetails" ItemsSource="{Binding GraphDetail}" IsReadOnly="True"
HorizontalAlignment="Right" Width="109" MouseLeftButtonUp="grdGraphDetails_MouseLeftButtonUp"
SelectedValuePath="Key" Height="179" />
</StackPanel>
</Grid>
<controls:ModalDialog x:Name="ModalDialog"></controls:ModalDialog>
<controls:ModalDialog1 x:Name="ModalDialog1"></controls:ModalDialog1>
</Grid>
Here i have two controls NodeXlControl1 and Datagrid1 on page seprated by grid seprator. when window loads NodeXlControl1 does not come within the grid column width and height. i want nodexlcontrol1 should be shown with in the grid column width and height. and i if it goes beyond the limits of width and height of column, scroll bar should come.

If your my:NodeXLControl internally has some scroll viewer (like some ItemsControl or ScrollViewer based child) then simply wrapping my:NodeXLControl in a Grid would do the trick.
StackPanel expands to overflow the children. Grid expands to outer's container's availability of space.
<Grid>
<my:NodeXLControl ... />
Should do the trick.
But if you my:NodeXLControl has no scroll viewer in it then you would need to wrap it inside one and provide absolute width or height to it or wrap it inside a Grid for it to bound to its avilable space and show scrollbars accordingly.
e.g.
<Grid>
<ScrollViewer ...>
<my:NodeXLControl ...>

Related

UserControl Expand Vertically when Window is expanded

I'm having trouble getting my UserControl to expand vertically when my window is expanded.
My UserControl currently sits inside a ItemsControl which is stretching correctly by setting the VerticalAlignment="Stretch" property on the ItemsControl.
I add the following UserControl to the ItemsControl:
<UserControl MinWidth="930">
<Grid VerticalAlignment="Stretch" Background="Red">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="730*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="400" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DockPanel Grid.Column="1" Grid.ColumnSpan="1" Grid.RowSpan="2" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Pink" LastChildFill="True">
<ItemsControl Name="itemPanelOverview" Grid.Column="1" Background="Black" Margin="0"/>
</DockPanel>
</Grid>
</UserControl>
The UserControl is called in an ItemsControl inside of a TabControl like so:
<TabItem>
<TabItem.Header>
HEADER EG
</TabItem.Header>
<ItemsControl Name="contentItems" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1" VerticalAlignment="Stretch" Background="Blue">
<Grid Height="35" Background="{DynamicResource GrayMenuGradient}" >
<Image Source="..." Stretch="None" />
<TextBlock Text="{Binding WelcomeMessage}" />
</Grid>
</ItemsControl>
</TabItem>
It appears that the ItemsControl (contentItems) is stretching as expected, as I can see the blue background stretching correctly.
I haven't set the height for this UserControl anywhere other than the Row Definitions. Is there something I'm missing?
There are at least two aspects at play here:
The first is that when you have items in an ItemsControl, each item is actually inside an ItemContainer, so it is the container that you want to stretch.
You can design the container by declaring an ItemContainerTemplate for your ItemsControl: http://msdn.microsoft.com/en-us/library/system.windows.controls.itemcontainertemplate.aspx
The second consideration is the ItemsPanelTemplate, which determines into what type of panel the items are placed. The ability of the items in the ItemsControl to fill up the available space is going to depend on the type of container as much as on the type of ItemContainer. For example, if you use a StackPanel for the ItemsPanelTemplate, it won't fill up available space because StackPanel grows and shrinks according to its contents. A DockPanel could potentially work, but only the last child would grow to fill available space. Perhaps a UniformGrid could do the trick.

WPF Scrollviewer won't scroll up

I have the following (simplified) xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="143*" />
<ColumnDefinition Width="135*" />
</Grid.ColumnDefinitions>
<TabControl Margin="12,29" Name="tabControl1" Grid.ColumnSpan="2">
<TabItem Header="TabItem1" Name="tabItem1">
<ScrollViewer Height="440" Name="scrollViewer1" Width="872" HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid Height="440" Name="grid1" Width="851" VerticalAlignment="Top" HorizontalAlignment="Left">
...
My problem is the scroll won't show up. What should I change ?
Thanks.
The content inside the ScrollViewer is smaller than the ScrollViewer itself. The ScrollViewer is used for being able to use scrollbars to show content that is larger than the area the ScrollViewer takes up.

WPF Element Binding With Dynamically Generated UI Elements

I have a page in which I have a grid with 2 columns, one accommodating 80* width and the other accommodating 20*. Beneath the grid is a stack panel to which I load UI elements (child stack panels) at runtime.
My objective is to bind the widths of the stackpanels to the columns of the grid. This works perfectly and the stackpenels resize if the dynamic content is mocked to be static in the design view. But when the application is run, the bindings fail and the widths are not bound.
Is there any way to refresh the bindings so that I can notify the stackpanels to refer the widths of the grid and configure its's size?
Updated:
This is what my XAML looks like:
<Page x:Class="WPFTestApp.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="resizeGrid"
Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="leftColumn"
Width="80*" />
<ColumnDefinition x:Name="rightColumn"
Width="20*" />
</Grid.ColumnDefinitions>
</Grid>
<StackPanel x:Name="contentPanel"
Grid.Column="0" Grid.Row="0" >
<!-- Dynamic StackPanels are added here -->
</StackPanel>
</Grid>
</Page>
In my code, I create StackPanel elements and add it to the contentPanel by saying:
contentPanel.Children.Add(...);
Unfortunately, I HAVE to use StackPanels here. :-(
The markup of a dynamically created StackPanel element is as follows (note that I use a Binding to the grid already in the XAML):
<StackPanel x:Name="element01"
Orientation="Horizontal"
Width="{Binding ElementName=resizeGrid, Path=ActualWidth}" >
<StackPanel x:Name="leftPanel"
Orientation="Vertical"
Width="{Binding ElementName=leftColumn, Path=ActualWidth}">
<!-- Content goes here -->
</StackPanel>
<StackPanel x:Name="rightPanel"
Orientation="Vertical"
Width="{Binding ElementName=rightColumn, Path=ActualWidth}">
<!-- Content goes here -->
</StackPanel>
</StackPanel>
The XAML code for my dynamic StackPanel elements are generated through an XSLT transformation
Note the xmlns:x namespace dynamic StackPanel. This also has to be done because of it being generated through XSLT
As far as I know setting the Width of a StackPanel with Orientation="Horizontal" will have no effect. The size of a StackPanel does not exceed the size of its content in its oriented direction.
Why do you "HAVE" to use StackPanels here? You almost certainly want DockPanels, given your objective. You won't have to bind or set anything, because the DockPanel will fill the cell automatically.
Try binding the ActualWidth instead of Width.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="resizeGrid"
Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="leftColumn"
Width="{Binding ElementName=contentPanel, Path=ActualWidth}" />
<ColumnDefinition x:Name="rightColumn"
Width="*" />
</Grid.ColumnDefinitions>
</Grid>
<StackPanel x:Name="contentPanel"
Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" >
<StackPanel Background="Yellow" Width="100" Height="25" />
<StackPanel Background="Green" Width="120" Height="25" />
<StackPanel Background="Red" Width="140" Height="25" />
<TextBlock Background="Gray" Text="{Binding ElementName=contentPanel, Path=ActualWidth}" />
</StackPanel>
</Grid>
The following changes I have done above:
1) Set the leftColumn to the ActualWidth of the contentPanel
2) Set the rightColumn to *
3) contentPanel HorizontalAlignment should be changed other then Stretch. Here I have changed it to Left
HTH
I found a solution for this issue. (Sorry for the late response)
What I did was, I cut and pasted the "resizeGrid" Grid control into the "contentPanel" Stackpanel.
As I mentioned above, the contents within the contentPanel are generated through an XSLT transformation and this surely creates a namespace reference issue. I noticed "element not found..." message in the Output window whenever this Window is loaded - this proved me right.
Inserting the "resizeGrid" into the "contentPanel" helped because then both the controls are within the same namespace and can be referenced for a PropertyBinding using "ElementName" attribute.
Thank you for your support! :-)

How can I prevent the grid splitter from resizing a column outside of the window bounds?

I have the XAML shown below (for example). If you drag the grid splitter as far as it goes to the left, and keep dragging the mouse, the right-hand column will grow in size outside the bounds of the window - obviously not what I want.
The problem is that I can't set a hard MaxWidth on the right-hand column because the user can resize the window, thus increasing the available space for that column.
So far I think I need to bind the MaxWidth of the right-hand column to something like the window's client area minus the MinWidth of the left plus the width of the splitter column. But I'd like to avoid that if possible. Thoughts?
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="450"
Height="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="100" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200" MinWidth="200" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Button>Monkey</Button>
</Grid>
<GridSplitter Grid.Column="1" Width="7" ResizeBehavior="PreviousAndNext" />
<Grid Grid.Column="2" Margin="4">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Header="Spaghetti" Margin="0, 0, 0, 5">
<ComboBox HorizontalAlignment="Stretch" VerticalAlignment="Stretch">Noodles</ComboBox>
</GroupBox>
<Expander Grid.Row="1" Header="Batman" IsExpanded="True" Margin="0, 0, 0, 5">
<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch">Batman!</Button>
</Expander>
</Grid>
</Grid>
</Window>
I'm having the same problem. Maybe this will be a partial answer. I bound the MaxWidth of the column I'm expanding to the ActualWidth of its grid. The goal being that the splitter never exceed the size of its grid. The binding works correctly but it's not achieving the goal because once my grid splitter gets to the edge of the grid, the grid starts resizing larger as I drag the splitter. If we can make the grid not resize with the splitter, this should work.

WPF Grid - Auto sized column not collapsing when content Visibility set to Visibility.Collapsed

I have the following simpl WPf grid, two columns, a button in each column, the first column auto sized and a splitter to allow column resizing.
An event handler is set up on the splitter MouseDoubleclick event. When the splitter is doulble clicked the button in the left column is collapsed.
Now, as column 1 is auto sized and the content is collapsed I would expect at this point that column 1 should effectively be hidden, however it is not.
Although its content is collapsed the column size does not change (remeber column is autosized).
Seems strange to me, I'd like the column to collapse - any idea what's happening here?
<Window x:Class="KingLayout.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Button x:Name="leftButton">Left</Button>
<Button Grid.Column="1" Margin="5,0,0,0">Right</Button>
<GridSplitter Name="verticalSplitter" ShowsPreview="True" Grid.RowSpan="1" Grid.Column="1" HorizontalAlignment="Left"
VerticalAlignment="Stretch" Width="5" MouseDoubleClick="verticalSplitter_MouseDoubleClick"/>
</Grid>
</Window>
private void verticalSplitter_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
leftButton.Visibility = leftButton.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
}
What's happening is that when you resize the column/row width/height with the GridSplitter, it sets the ActualHeight (or ActualWidth) of the column/row.
You should use a trigger to set row's height to auto (or zero) when your control is collapsed.
Get me updated with this.
In my case, I was able to use StackPanels and setting the Visibility="Collapsed" which caused it to properly resize.
<StackPanel Orientation="Vertical" Margin="5">
<StackPanel Orientation="Horizontal">
<!-- Some controls -->
</StackPanel>
<StackPanel Orientation="Horizontal" Visibility="{Binding YourVisibilityProperty}">
<!-- Some controls -->
</StackPanel>
</StackPanel>
It's because the splitter keeps its position in the grid, it pulls the first column, why don't you try an expander?
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Expander ExpandDirection="Left">
<Button x:Name="leftButton">Left</Button>
</Expander>
<Button Grid.Column="1" Margin="5,0,0,0">Right</Button>
</Grid>

Resources