How to bind 2 grid column widths together in xaml - c#

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.

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.

Does SelectiveScrollingGrid only freeze columns on first column?

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>

Creating binary tree with wpf

I'm trying to create a binary tree in wpf that will look like that:
So, I created three classes - Node (Abstract), And OneTypeNode, And TwoTypeNode (those are example, btw, MVVM is important here).
Every node also have reference to his two sons.
in the xaml, it look something like that:
<StackPanel>
<Grid ShowGridLines="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Border Grid.Column="1" Grid.Row="0" x:Name="CircleFather" CornerRadius="5"
Width="40"
Height="40"
Background="DarkKhaki"
Margin="0 20 0 0"
BorderThickness="1" >
</Border>
<ContentControl Grid.Row="2" Grid.Column="0" Content="{Binding RightSon}" Margin="10"></ContentControl>
<ContentControl Grid.Row="2" Grid.Column="2" Content="{Binding LeftSon}" Margin="10"></ContentControl>
</Grid>
<Line ></Line>
</StackPanel>
Which actually let me create sons recursively!
But there are two main problems: first of all is the size, I can't control the size of the grid since I don't know how many sons are gonna be on every side. ALSO - I don't have any idea to how create the lines between every two nodes. Any idea?
Thank you very very much!

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.

Layout in silverlight

I am running into a layout issue which I am not sure how to solve. Here is how my xaml looks like,
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid x:Name="abc" Grid.Row="0" Grid.Column="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0"></Button>
<TextBox Grid.Row="0" Grid.Column="1"></TextBox>
</Grid>
</Grid>
<Grid Grid.Row="0" Grid.Column="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0"></Button>
<TextBox Grid.Row="0" Grid.Column="1"></TextBox>
</Grid>
</Grid>
</Grid>
Now the layout of the above xaml is exactly as what I want. However, I have one additional requirement. At runtime I need to make grid "abc" collapsable. And the other grid needs to fill the entire width. If I use star sizing width then if "abc" is collapsed it behaves more like hidden than collapsed. Collapse seems to work with Auto sized widths but then it doesn't give me propotional sizing as required. Is there a way to accomplish this. Note, I only have access to Grids, StackPanels, and Canvas for layout of my items (no DockPanel). Please let me know of any ideas along with any code snippets. Thanks.
Hard tell your intent in the layout, but here is a sample to get you started.
I changed the ColumnDefintion width from * to Auto in the Click event and set the Visibility to Collasped for "abc" Grid. I used the second button to change these values for test purposes, and I removed an extra level of Grid that is not needed.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnToCollapse" Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid x:Name="abc" Grid.Row="0" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0"></Button>
<TextBox Grid.Row="0" Grid.Column="1"></TextBox>
</Grid>
<Grid Grid.Row="0" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Click="Button_Click" />
<TextBox Grid.Row="0" Grid.Column="1"></TextBox>
</Grid>
</Grid>
Here is the button click event:
private bool _toggle = true;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (_toggle)
{
ColumnToCollapse.Width = GridLength.Auto;
abc.Visibility = Visibility.Collapsed;
_toggle = false;
}
else
{
ColumnToCollapse.Width = new GridLength(1, GridUnitType.Star);
abc.Visibility = Visibility.Visible;
_toggle = true;
}
}
Had the same problem, only made worse by having a splitter in a middle third column.
Basically I wound up binding the column widths (each of them) to properties that return auto in one mode and star in the other mode. Make sure you implement INotifyPropertyChange for the properties and call the onchange helper for both column property names when you change the flag controlling the layout.

Categories

Resources