Does SelectiveScrollingGrid only freeze columns on first column? - c#

I have a requirement to freeze the right-hand column in a grid when scrolling. Elsewhere, I am using the SelectiveScrollingGrid to freeze the left-hand column just fine, but when the frozen column is right-hand it no longer works.
Here is some XAML:
<!-- Right aligned frozen column results in clipping when scrollbar appears -->
<SelectiveScrollingGrid>
<SelectiveScrollingGrid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</SelectiveScrollingGrid.ColumnDefinitions>
<DataGridCellsPresenter Grid.Column="0" ItemsPanel="{TemplateBinding ItemsPanel}" />
<DataGridRowHeader Grid.Column="1"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical">
</SelectiveScrollingGrid>
The above does not work (when you resize a window containing a grid the DataGridRowHeader area becomes clipped when the scrollbar appears).
The below XAML works just fine however:
<!-- Left aligned frozen column works! -->
<SelectiveScrollingGrid>
<SelectiveScrollingGrid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</SelectiveScrollingGrid.ColumnDefinitions>
<DataGridCellsPresenter Grid.Column="1" ItemsPanel="{TemplateBinding ItemsPanel}" />
<DataGridRowHeader Grid.Column="0"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical">
</SelectiveScrollingGrid>
Can SelectiveScrollingGrid be used with a frozen column on the right? If not is there another solution?

you can freeze any column you like, other columns would scroll pass/float underneath the frozen columns, in below snippet the text block in the first column is only allowed to scroll vertically ( horizontal scroll will have no effect on this text block)
<SelectiveScrollingGrid>
<SelectiveScrollingGrid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=XX,Path=ActualWidth}" ></ColumnDefinition>
<ColumnDefinition Width="{Binding ElementName=LastName,Path=ActualWidth}"></ColumnDefinition>
<ColumnDefinition Width="{Binding ElementName=Address,Path=ActualWidth}"></ColumnDefinition>
</SelectiveScrollingGrid.ColumnDefinitions>
<TextBlock Text="1111111111111" Grid.Column="0" SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" ></TextBlock>
<TextBlock Text="2" Grid.Column="1"></TextBlock>
<TextBlock Text="3" Grid.Column="2"></TextBlock>
</SelectiveScrollingGrid>

Related

ScrollViewer is not working with grid columns

I have this built and I add text boxes to it programmatically and update after each addition but the scrollViewer never becomes scrollable just grayed out arrows. I'm only adding textBoxes to one of the stackPanels, could that be it? If so is there some work around for that? I'd appreciate any help, I've spent much too long on this silly problem.
<ScrollViewer x:Name="scrollViewerMain" VerticalScrollBarVisibility ="Visible" HorizontalAlignment="Center" Height="368" Width="410" VerticalAlignment="Top" Margin="150,309,150,-35.5">
<Grid HorizontalAlignment="Left" Height="368" VerticalAlignment="Center" Width="410" ScrollViewer.CanContentScroll="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel x:Name="stackPanelPlayerNames" Grid.Column="0" Height="368"/>
<StackPanel x:Name="stackPanelWins" Grid.Column="4" Height="368"/>
<StackPanel x:Name="stackPanelHours" Grid.Column="5" Height="368"/>
<StackPanel x:Name="stackPanelKills" Grid.Column="1" Height="368"/>
<StackPanel x:Name="stackPanelDeaths" Grid.Column="2" Height="368"/>
<StackPanel x:Name="stackPanelRatio" Grid.Column="3" Height="368"/>
</Grid>
</ScrollViewer>
Your Grid should not have a fixed height. If your Grid (inside your ScrollViewer) is ALWAYS 368 pixels tall, and that your ScrollViewer is bigger than 368 pixels tall, then there is always no overflow.

How to bind 2 grid column widths together in xaml

I'm hoping someone can make this easy.
I have a grid with 5 columns, columns 1 and 3 contain splitters. What I want to happen is when I move one splitter have the other one move to match such that the effect is the first and last columns being sized together.
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" x:Name="col1"/>
<ColumnDefinition Width="5" />
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="5" />
<ColumnDefinition Width="{Binding ElementName=col1, Path=ActualWidth}" />
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" Background="Red"/>
<GridSplitter Grid.Column="3" HorizontalAlignment="Stretch" Background="Red"/>
</Grid>
Needless to say the above doesn't work. And even if it did it would only allow for using the first splitter not the second. Can anyone shed some light?
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" x:Name="col1"/>
<ColumnDefinition Width="5" />
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="5" />
<ColumnDefinition Width="{Binding ElementName=helperGrid, Path=ActualWidth}" />
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" Background="Red"/>
<GridSplitter Grid.Column="3" HorizontalAlignment="Stretch" Background="Red"/>
<Grid Grid.Column="0" x:Name="helperGrid" Width="{Binding ElementName=helperGrid2, Path=ActualWidth}" MinWidth="100"/>
<Grid Grid.Column="4" x:Name="helperGrid2"/>
</Grid>
This worked for me, I changed the first column's width to auto and used two helper grids in the first and last columns
After much playing around I could get close but not completely what I was looking for. So I ended up placing a Grid in each if the splitter columns instead of GridSplitters and handling the PreviewMouseDown event on the Grid and also the PreviewMouseUp and PreviewMouseMove events of the parent control to implement my own resizing. This was used to detect dragging in columns 1 and 3 and resize colunmns 0 and 3 together. Sadly the code has become rather interwoven with the rest of my control so isn't easy to post. Maybe one day when my xaml improves I'll be able to break the functionality out into a properly reusable control.

How to dock an element to another while respecting parent container size?

I want to layout two labels in a fixed width column. One left-aligned and growing to the right, the other directly to the right of it.
When the combined width of the labels is smaller than the available space there should be empty space to the right. This is achieved with this markup:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock TextTrimming="CharacterEllipsis" Text="Sample Name" />
<Label Content="Text" Foreground="#AAAAAA" Grid.Column="1"/>
</Grid>
When the first label is too large, the text is trimmed and the label at the right should not be pushed out of the column. This is achieved with this markup:
<DockPanel LastChildFill="True">
<Label Content="Text" Foreground="#AAAAAA" DockPanel.Dock="Right" />
<TextBlock TextTrimming="CharacterEllipsis" Text="A Really Really Long Sample Name" />
</DockPanel>
How can I get the same results (the screenshots) without different pieces of Xaml?
Turns out it was something that I thought I had tried. This did it for me:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock TextTrimming="CharacterEllipsis" Text="Sample Name" />
<Label Content="Text" Foreground="#AAAAAA" Grid.Column="1" />
</Grid>

How do I make a textbox in WPF fill the horizontal space between other items?

I'm trying to have a stackpanel of radio buttons on the left, a button on the right, both of fixed width, and a text box between them that stretches to fill the space as the window is resized.
This is what seems like should work:
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel HorizontalAlignment="Left">
<RadioButton GroupName="FibOptions" IsChecked="True">Term Closest To N:</RadioButton>
<RadioButton GroupName="FibOptions">Nth Term:</RadioButton>
</StackPanel>
<TextBox x:Name="FibInput" Grid.Column="1" />
<Button Grid.Column="2" x:Name="FibGen" HorizontalAlignment="Right">Generate</Button>
</Grid>
But the above results in a tiny text box that's basically a vertical line right in the middle of the area. Any help with this?
Set the column width to *, which tells it to fill the remaining space, and set the other two to auto:
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />

WPF Data Grid - How to hide the next column/row that is visible?

I'm using a WPF data grid to bind to an object (i.e. not a database). I have the horizontal alignment on Stretch. I currently have it within a Border, which is within a Grid.
However when I run the application the DataGrid has a blank column and grid showing. That is say I have 5 columns & 5 rows, then there is a blank 6th column and row showing. See image:
Question - How can I get rid of these blank rows? Note that the contents of the DataGrid are populated programmatically (i.e. are not static).
thanks
EDIT: I got the extra row fixed (via CanUserAddRows), but I still have an issue with the extra column on the right.
The issue with the extra column on the right seems to be to do with automatically setting column widths. The DataGrid is actually setup (see XAML below) such that there is a GridSplitter just on it's right. When I move the GridSplitter I note that the DataGrid columns don't resize automatically. So overall the issue is both (a) on startup there is a partial extra column visible, and (b) after moving the GridSplitter they don't resize either.
Any ideas on how to get this working?
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="Summary" Grid.Row="0" HorizontalAlignment="Center" />
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<RadioButton IsChecked="{Binding Path=Period, Converter={StaticResource enumBooleanConverter}, ConverterParameter=AllTime}" Grid.Column="0">All Time</RadioButton>
<RadioButton IsChecked="{Binding Path=Period, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Month}" Grid.Column="1">Month</RadioButton>
<RadioButton IsChecked="{Binding Path=Period, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Week}" Grid.Column="2">Week</RadioButton>
<RadioButton IsChecked="{Binding Path=Period, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Day}" Grid.Column="3">Day</RadioButton>
</Grid>
<Border Grid.Row="2">
<DataGrid Name="SummaryDataGrid" HorizontalGridLinesBrush="#FF726868" VerticalGridLinesBrush="#FF726868" AlternatingRowBackground="#FFD0F896" CanUserReorderColumns="False" CanUserResizeRows="False" CanUserAddRows="False" CanUserSortColumns="True" CanUserResizeColumns="False" ColumnWidth="Auto" />
</Border>
</Grid>
<GridSplitter HorizontalAlignment="Right"
VerticalAlignment="Stretch" Grid.Column="1" ResizeBehavior="PreviousAndNext"
Width="5" Background="#FFBCBCBC"/>
<Grid Grid.Column="2" Name="RTChartGrid">
<-- CUT -->
</Grid>
</Grid>
as per http://social.msdn.microsoft.com/Forums/en/wpf/thread/f7b6845d-f9d6-4f0d-aa88-a338641522ee
I simply attached a Loaded handler to the Datagrid and set all of the additional columns to a width of 0 and made them hidden.

Categories

Resources