programatically set width of a column within a grid - c#

Is it possible to set the width of a column for Grid within Silverlight? I have a grid (not a grid view) with two columns. ColumnA and ColumnB. What I am trying to accomplish is when a user clicks on a button within ColumnA the width of ColumnA is set to .01. ColumnB should then expand the entire width of the grid to fill the remaining area. Similar to how you pin or un-pin a dock panel?
Is this the best approach or should I revert back to a dockpanel and let SL handle it? I'd prefer to manage it myself vs. using a RAD control as I think it is a little bloated for such a small and seemingly simple task.
Another thought I had was to use a gridsplitter but I was unsure as to how to programmatically collapse or expand the column using the gridsplitter? Hence my current predicament. Any suggestions would be greatly appreciated.
Thanks in advance

Give your ColumnDefinition a name via the Name attribute, e.g.:
<ColumnDefinition Width="100" Name="FooColumn"/>
Then you can assign it a new Width in code whenever you want:
FooColumn.Width = new GridLength(1);
(edit: should have used the same name in both places... oops.. you get the idea though)

Try this
<Grid x:Name="LayoutRoot" Background="White" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<sdk:GridSplitter />
</Grid>
LayoutRoot.ColumnDefinitions.First().Width = new GridLength();

Related

GridSplitter with a fixed panel (grid column) when grid (usercontrol/window) size changes

Basically, I want to emulate the GridSplitter.FixedPanel feature available in WinForms.
XAML :
<UserControl ...>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="3" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Column="0" />
<GridSplitter
Grid.Column="1" Width="3" VerticalAlignment="Stretch"
Background="Transparent"
ResizeDirection="Columns" ResizeBehavior="PreviousAndNext" />
<ListBox Grid.Column="2" />
</Grid>
</UserControl>
This works great and resizes each side accordingly. But suppose we resize the (not maximized) window containing this UserControl, now both grid columns on each side of the splitter (auto) resizes. The 4/5 and 1/5 column width ratios are required for space distribution upon start, but practical space allocation depends on the displayed data, hence the grid splitter.
How to make one column retain its width (the one on the right for instance as it hosts properties, tools, etc.) while the window gets resized around, hence only making the left column resize.
I have some ideas :
Just code behind to emulate FixedPanel like in WinForms : DragStarted, DragCompleted and some private fields for eg.
Use a Behavior like suggested in this SO topic (I have not used Behaviors for years, have some refreshing to do - To be honest, I really hope there is an XAML-only way, but if there isn't, I prefer the code behind way where I expose new dependency propertie(s) rather than a behavior)
I believe I'm missing one feature of WPF to achieve this the WPF way. Almost all times I thought "well I guess I have to code behind this...", there were the WPF way, usually simplier, safer, easy to design and better, performance wise. That's why I'm asking directly, and maybe would help someone else looking for the feature.
Programming language (for that matter) : C#
Edit : after Léo Savador's answer :
See : there were a WPF way (toying with XAML ColumnDefinition Width properties) and little code :
bool p_layoutInitialized = false;
void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) {
if (e.NewSize.Width > 1) { // optional : && e.NewSize.Height > 1
if (!p_layoutInitialized) {
RightColumn.Width = new GridLength(MainGrid.ActualWidth / 5);
p_layoutInitialized = true;
}
}
}
where RightColumn is the name of the ColumnDefinition on the right, and MainGrid the name of the Grid.
Thanks you so much, was in the process of writing heavy code behind. You saved me so much time :D
PS : Please do not assume I'm a WinForm fanboy. I'm only mentionning WinForms to give a comparative example of the desired feature, could have used CSS and JS, but much harder to describe.
Here is a simple solution that I can recommend to you for your need:
For your right column, instead of using a dynamic width (1*), use a fixed width:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3" />
<ColumnDefinition Width="160" />
</Grid.ColumnDefinitions>
If you set a fixed width of 160:
You will get the same initial result (1/5 of the initial width of your window)
You will be still able to resize your grid
On resize, your right column will keep it's width
And you have also the possibility to use code behind to calculate the desired fixed width at startup, according to the window initial width, to be more "dynamic".

Control the width of a listbox inside a grid

I have a view. The grid inside the view is divided into 2 columns.
<Grid x:Name="grdView">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
Inside the Auto column(Column 0), I have another view
<Border Grid.Column="0" Style="{DynamicResource BorderStyle}">
<Views:ViewerDataBrowser x:Name="dataBrowser" DataContext="{Binding ViewDataBrowserInstance}" />
</Border>
Inside this view I have a listbox and a data template defined for the list box.
Inside the data template I have 2 rows and 2 textblocks in each of them.
Issue
When the textblock characters are more than the width of the column, the listbox is being stretched and a scroll bar is also displayed. I don't want that to happen. I want the text to be truncated and show ... at the end.
I tried text trimming and text wrapping for the textblock. But it did not work. I also tried to set the width of data template to Auto, but it is not working. The only possible solution working for me is to set the width of the data template to a constant value.
I want the listbox to fit inside the grid and not show the scroll bar even though the text block have lengthy text. Please suggest a solution.
You can get and set the horiztonalScrollBar property of a listBox as described on the MSDN site. When setting the width of the listBox (pre-uwp) you may use device independent pixels (DIPs). Also, instead of using a constant, you may set the width proportional to that of the listBox's container--though not recommended vs DIPs and auto-resizing since certain dimensions behave better.
The issue is caused since the column width of the grid was set to "*".
When I changed the column width to constant, ie the same width as that of the parent, the issue seems to be fixed.
Regarding the truncation of the textblock, I set the textbox trimming property.

ExtentWidth of TextBox not set correctly

I recently experienced a strange behavior of text boxes.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Content="Test"/>
<TextBox Grid.Column="1" TextWrapping="Wrap" Text="testtesttesttesttesttesttesttesttesttesttest"/>
<Control Grid.Row="1" Grid.ColumnSpan="2" Width="280"/>
</Grid>
In this example code I have a Grid with 2 rows and 2 columns. The 2nd column is set to a fixed width. The TextBox has TextWrapping set to Wrap.
In the second row I have a Control with a fixed width that is higher than the Grid would normally be. This increases the ActualWidth of the second column from 200 to about 250.
The actual width of the TextBox also increases to match the new width of the column.
When I now add a long string to the text box the text, it doesn't use the full width of the TextBox but instead wraps way to early and leaves about 40 pixels at the end of the TextBox empty.
I've found out that the TextBox has a readonly ExtentWidth property. This property is responsible for the wrapping. In my example the values of the ExtentWidth is about 180, which is the 200 from the width of the grid column minus margins and paddings.
What can I do to fix the wrapping in the TextBox?
EDIT: This question is not a duplicate of Looking for explanation for WPF Grid ColumnSpan behavior.
That question explains what happens to the Widths of the grid columns. But it doesn't answer the question regarding the wrapping behavior of the TextBox.
I honestly don't understand the "why" part, but until someone provides a meaningful explanation, here are some workarounds:
Set an explicit width on the TextBox
Set MaxWidth on the column instead of Width
Bind the width of the TextBox to that of another element inside the same column. e.g:
<TextBox Grid.Column="1" Width="{Binding ActualWidth, ElementName=rect}" ... />
<Rectangle Grid.Column="1" x:Name="rect"/>
Note that the last one is the only usable workaround if you need to be able to change the column width at runtime and want the TextBox (and the wrapping) to change with it.

Winrt Xaml Grid ROw not filling Space with *

I have the problem, that my Grid is not filling the space as I want it.
Here some code:
<HubSection>
<Grid Width="850">
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
<RowDefinition Height="*"/>
<RowDefinition Height="310"/>
</Grid.RowDefinitions>
<Input:RadDatePicker Grid.Row="0" Value="{Binding CurrentDate, Mode=TwoWay}" />
<ListView
Grid.Row="1">...
</ListView>
<Grid Height="310"
Grid.Row="2">...
</Grid>
...
I want that the middle row is filling the space up of the hubsection. Instead it now just fills up when the listview contains enough items.
Any idea?
Now the filled ListView:
I would try setting the VerticalContentAlignment of the HubSection to Stretch as well as setting the VCA of the outer grid to that option. I'm suspecting the default might be Center or Top and so the minimizing vertical alignment control from the parent control and the expanding star-sized row setting of the inner grid come in a little bit of a conflict that some layout prioritizing rules probably resolve in getting the VCA rule to win.
For similar layout issues it is usually best to analyze with a visual tree debugger such as the XAML Spy or WinRT XAML Toolkit. You can also try tracing these various properties by walking the visual tree with the VisualTreeHelper class yourself.

How do I add dynamic spacing between controls? (with pics)

My question is simple. What is the best way to achieve what you see the pic below in WPF?
At the moment this is a horizontal StackPanel, with the right padding of the checkbox set to 90. This works okay, but if you resize the window it's no good anymore, unless maybe you re-adjust the padding in the window's resize event, but that seems clunky when using a layout manager.
I am coming from a Qt background, and in Qt I would use a "stretch" element between the buttons and the checkbox to push them apart dynamically. Is there a similar concept in WPF? If not, how do I achieve this so that it will support dynamic resizing?
Thanks!
Use the corrent Panel implementation, in this case a Grid would work best:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<CheckBox>Details</CheckBox>
<Button Grid.Column="1">Exit</Button>
<Button Grid.Column="2">Reset</Button>
</Grid>

Categories

Resources