I am trying to work with grid Splitter.
Here i have 2 column which can be resized. other column headers are disabled.
How I can resize the column width of GridViewColumn when grid Splitter is used?
Here, i was trying to achieve something like when the gridsplitter is moved, instead of hiding column of datagrid, each resizable columns should be resized equally.
To solve this, instead of giving a width to resizable column as auto or fixed value, give it ***** like
<DataGridTextColumn Header="Owner Name"
Width="*"
MinWidth="100"
MaxWidth="250"
CanUserResize="True"
Binding="{Binding OwnerName}" />
and gridsplitter as
<GridSplitter x:Name="gridSplitterStatusBar"
Grid.Column="0" Grid.Row="1"
ResizeDirection="Columns"
Background="Gray"
VerticalAlignment="Stretch"
HorizontalAlignment="Right"
Cursor="ScrollWE"
Width="2"/>
so whenever you will try to resize the datagrid, resizable columns will take the available space.
Related
I've got a grid with 3 columns: the first has its Width set to "*", which I have been led to believe will make it fill up any remaining space left by the other columns. The second has a width of 8, and the third's Width is set to "Auto" so its size changes depending on its contents.
In my 2nd column I have a GridSplitter, so that when dragged I can change the width of both the first and third columns. This works fine, the issue is that I have a grid in my third column that, when toggled, will have its visibility set to collapsed. When collapsed, I need the first column to fill all of the remaining space. I tried to do this many ways:
Set HorizontalAlignment on first column to Stretch
Bound the Grid.Rowspan of the first column to the visibility of the third one, so that when when hidden the Rowspan will change to 3 and, since its width is using "*", it should theoretically use all of the available space in all 3 columns.
The weird thing is that, if I do not resize the columns using the GridSplitter, then the first column will fill all remaining space properly. Yet after resizing, the first column will not budge. It's almost as if, when dragging the GridSplitter to resize the columns, WPF change the width of both columns to become absolute instead of their star and auto values, making it so they will not fill the space after a resize.
XAML Code (condensed) as requested:
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid x:Name="AssetListViewGrid" Grid.Column="0" Grid.RowSpan="{Binding Visibility, ElementName=AssetViewMetadataSplitter, Converter={StaticResource SplitterVisibilityToRowSpanConverter}}" Margin="0 4 0 4">
<!-- irrelevant code -->
</Grid>
<GridSplitter x:Name="AssetViewMetadataSplitter" Grid.Column="1" Opacity="0.8" HorizontalAlignment="Center" Width="6" Margin="3 5 1 5" ToolTip="Grab to resize" Visibility="{Binding IsChecked, ElementName=GridHeaderVisibilityToggleButton, Converter={StaticResource VisConverter}}"/>
<Grid x:Name="MetadataGrid" Margin="4 2 4 2" Grid.Column="2" DataContext="{Binding MetadataViewModel}" Visibility="{Binding IsChecked, ElementName=GridHeaderVisibilityToggleButton, Converter={StaticResource VisConverter}}">
<!-- irrelevant code -->
</Grid>
I just ran into this as well. In my app it seemed that a GridSplitter was in fact changing the width values to absolute instead of * also, so I'm guessing that is the behavior.
I ended up using code-behind to solve it. First, name column 1:
<ColumnDefinition Width="*" x:Name="Column1"/>
Then, add an event handler for when your MetadataGrid visibility changes, & call this code to reset Column1 to a * width to fill the rest:
Column1.Width = new GridLength(1, GridUnitType.Star);
You might also try doing something in the XAML with style triggers to reset the Column1 width to * based on the MetadataGrid's visibility state. My case was much more complex with custom sizes & varied conditions & expanders, so I used code-behind, so I'm not sure if xaml triggers would work for yoU or not . Hopefully that helps though.
I solved it by adding empty 10000X1000 rectangle inside it
<Grid Grid.Row="1" Grid.Column="1" Height="auto" HorizontalAlignment="Left" SizeChanged="Grid_SizeChanged">
<Image x:Name="currentImage" Height="auto" Width="auto" />
<Rectangle Width="10000" Height="10000" ></Rectangle>
<Canvas x:Name="currentImageOverLay"/>`</Grid>
I am having an issue with column sizing in a WPF datagrid.
Below I have an example with 2 equal datagrids. Both have 1 fixed column (Code) and 1 column set the fill with * sizing (Description). They are both contained within a layout grid.
The first datagrid is contained within a fixed sized column (WorkingGrid) in the layout grid. It works fine. The fixed "Code" column is the correct width and the * sized "Description" one fills the remaining space.
The second datagrid is contained within an auto sized column (BrokenGrid) in the layout grid. It has exactly the same setup as the other datagrid yet ignores all datagrid column widths specified. They appear to become the default minimum size, which I think is 20. The strange thing is, the actual datagrid itself expands to fill up the remaining space and so do all other controls and layout grids that sit in that BrokenGrid column. The Datagrid columns remain squashed down to 20px, including the fixed "Code" one which had a width of 100 specified.
Here is the example, simplified greatly:
<Grid Attached:ReadOnlyOptions.IsReadOnly="{Binding IsReadOnly}">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="WorkingGrid" Width="500"/>
<ColumnDefinition x:Name="BrokenGrid" Width="Auto"/>
</Grid.ColumnDefinitions>
<DataGrid Grid.Column="0" VerticalAlignment="Top" ItemsSource="{Binding AllResults}">
<DataGrid.Columns>
<DataGridTextColumn Header="code" Width="100" Binding="{Binding Path=Code}"/>
<DataGridTextColumn Header="description" Width="*" Binding="{Binding Path=Description}"/>
</DataGrid.Columns>
</DataGrid>
<DataGrid Grid.Column="1" VerticalAlignment="Top" ItemsSource="{Binding AllResults}">
<DataGrid.Columns>
<DataGridTextColumn Header="code" Width="100" Binding="{Binding Path=Code}"/>
<DataGridTextColumn Header="description" Width="*" Binding="{Binding Path=Description}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
In the real world example there is actually a large hierarchy of grids within grids, but if any of the columns (that directly or indirectly contain the datagrid) in any of those grids the whole way up the hierarchy chain has a width of auto, it breaks ONLY the datagrid columns. If I fix or * the width of those columns, the datagrid columns behave correctly.
I need this to work so I can have a set of controls/datagrids contained within a grid that all automatically expand to the width of the widest content, but all datagrids within the set have a column that fills that datagrid's width (minus whatever fixed widths columns are in there).
If it possible use a Width="*" for BrokenGrid.
The second solution is set fix width for second DataGrid
The difference between "*" and "Auto":
"*" - takes all left place (no matter how much element in column needs)
"Auto" - takes all left place or less (as much as element in column needs)
In your case, DataGrid tells BrokenGrid, that its needs 42.0px (I think i could be some DataGrid bug, it should wants at least 100px)
I have a problem with a ScrollViewer that I use to scroll a user control that contains a data grid. Without the scroll viewer the columns fill the data grid as I want but when adding a scroll viewer the columns shrink to ~15px. I was able to simplify my layout and can still reproduce this behaviour.
When binding the datagrid width to another control the columns have their normal with, but that has unsuprisingly the same effect as a fixed width on the datagrid.
I guess I'm not the first one who has this problem. How can I work around this behaviour to have my grid adjusting its size to the available space and give it's columns a propotional width?
With scrollviewer:
and without:
<Window x:Class="GridTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<Grid MinWidth="200">
<DataGrid Margin="0" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="Column A" Width="*"/>
<DataGridCheckBoxColumn Header="Column B" Width="*"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</ScrollViewer>
Yeah, I had this problem a while ago, I resorted to a workaround, I will post here just incase its useful
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<Grid x:Name="grid" MinWidth="200">
<DataGrid Width="{Binding ElementName=grid, Path=ActualWidth}">
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="Column A" Width="1*"/>
<DataGridCheckBoxColumn Header="Column B" Width="1*"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</ScrollViewer>
The trick was to give the DataGrid a width, in this case I bound back to the containing element
Or if you don't use the HorizontalScrollBar you can disable it, this will allow the ScrollViewer to calculate a width allowing the DataGrid to calculate a width.
I experienced the same thing last week.
Typically, this problem occurs when you have the following elements :
A DataGrid with undefined width placed inside a ScrollViewer with the HorizontalScrollBarVisibility property set to Auto
At least one DataGridColumn has an unlimited/undefined width (e.g : Width="*")
Actually, the solution depends on your needs :
Either you want your DataGridColumns to take all the available space of your DataGrid when the Window is showing (even if there's no displayed data) : in this case, sa_ddam213's answer can help you to cope with.
Or you don't mind having some blank spaces between your last column and the DataGrid right border on Window's first show.
For the last option, you just need to set fixed widths for your DataGridColumns (or just don't define it if you don't want to, this is not very important as columns can be easily resized by the user through a double-click). In this context, your DataGrid can be defined without a width.
Here is an example :
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<Grid x:Name="grid" MinWidth="200">
<DataGrid>
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="Column A" Width="100"/>
<DataGridCheckBoxColumn Header="Column B" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</ScrollViewer>
By this way, if a column content runs over the container after a column auto-resizing, a horizontal scroll bar will appear.
The solution prevents the problem mentioned by mardok.
<ScrollViewer x:Name="Scroll"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<StackPanel Width="{Binding ElementName=Scroll, Path=ViewportWidth}"
MinWidth="150">
<TextBlock Text="Other UI Controls"/>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Col1" Width="*"/>
<DataGridTextColumn Header="Col2" Width="50"/>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</ScrollViewer>
Bind the width of the container panel to the ViewportWidth of the ScrollViewer
Set MinWidth for the container panel.
I have a DataGrid with 2 templated columns:
the first includes a combobox and I let it size to fit its content, as this is at most one or two words;
the second instead includes a textbox where text might become somewhat long.
So here I set MaxWidth=somevalue to avoid its width expand beyond the datagrid container, I do the same for its MaxHeight, and set text to wrap. Anyway, I'd like the textbox to size its width to fill all the remaining space in the datagrid container: if the user shrinks or enlarges the 2nd column, I'd like the textbox to shrink or enlarge accordingly so that their width stay in synch. Text will wrap, and scrollbars appear as necessary.
Both controls in the grid are bound to a data source in a MVVM scenario. Could anyone give a hint for letting the template textbox width expand/contract with the container column? Here is my sample code:
<DataGrid ...>
<DataGrid.Columns>
<!-- 1 -->
<DataGridTemplateColumn ...>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox .../>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!-- 2: THIS TEXTBOX SHOULD EXPAND/CONTRACT WITH ITS CONTAINER COLUMN -->
<DataGridTemplateColumn ...>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox TextWrapping="Wrap"
MinWidth="400" MaxWidth="700"
MaxHeight="400"
ScrollViewer.VerticalScrollBarVisibility="Auto" .../>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Set HorizontalAlignment="Stretch" on your TextBox and set your DataGrid's Column Width="*"
Within a Groupbox I have a Listbox, ListboxItems are defined in the XAML as well. The Listbox is defined:
<ListBox Name="lvAvoidCountry" Margin="5,5,5,5"
Background="Transparent"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
Items are defined like this:
<ListViewItem >
<CheckBox Name="chkAlbanien" Tag="55">
<StackPanel Orientation="Horizontal">
<Image Source="images/flag_albania.png" Height="30"></Image>
<TextBlock Text="Albanien" Margin="5,0,0,0"></TextBlock>
</StackPanel>
</CheckBox>
</ListViewItem>
If I remove the Scrollviewer Settings I get horizontal scrolling and the Items are well formatted - correct width. If I use the scrollviewer settings the items get cut off so that all items are placed on the listbox. (eg. the flag is shown, the checkbox is shown but the text is just "Alba").
Thanks for any hints!
As the name implies, ScrollViewer.HorizontalScrollBarVisibility="Disabled" disables horizontal scrolling. If you do that, but your ListBoxItems are too long, they'll get cut off. The StackPanel won't grow or shrink to fit into the ListBox, and it won't "wrap" your items to fit into the ListBox if it's too narrow, even if you add TextWrapping to the TextBlock. It's very stubborn. I think your main problem is that StackPanel.
Instead of a StackPanel, try using a Grid with 2 columns defined like so:
<ListViewItem >
<CheckBox Name="chkAlbanien" Tag="55">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="images/flag_albania.png" Height="30"/>
<TextBlock Grid.Column="1"
TextWrapping="Wrap"
Text="Albanien" Margin="5,0,0,0"/>
</Grid>
</CheckBox>
</ListViewItem>
Auto will "shrinkwrap" the image columns, and * will give the text all remaining space. Then add TextWrapping to your textblock in case it's still too long.
Edited: added more complete code example and changed my answer slightly.
if you want vertical scrolling in a listbox then don't put it in a stackpanel,instead use a grid.