Radiobutton Even Horizontal Alignment - wpf

Is there a way to evenly layout radiobuttons including the radiobutton text? I have tried StackPanel with Orientation=Horizontal, DockPanel and UniformGrid but I have not achieved the exact look I am going for which is an even amount of white space between the controls without having to wrap or truncate the text.
<GroupBox Name="grpLegend" Header="{x:Static res:Strings.ChartOptionsDisplayControlView_GroupBox_Legend}">
<ItemsControl
ItemsSource="{Binding IsAsync=True, Path=AvailablePitchbookLegendPosition}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding IsAsync=True, Path=DisplayName}"
IsChecked="{Binding IsAsync=True, Path=IsSelected}"
GroupName="LegendPosition"
Margin="2,3.5" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</GroupBox>

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<RadioButton Grid.Column="0" Content="Left"/>
<RadioButton Grid.Column="1" HorizontalAlignment="Center" Content="Center"/>
<RadioButton Grid.Column="2" Content="Right"/>
</Grid>
If this Grid was part of a list's ItemTemplate and you wanted to synchronize the widths of the grid's columns you should use the SharedSizeGroup property.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="c1"/>
<ColumnDefinition SharedSizeGroup="c2"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="c3"/>
</Grid.ColumnDefinitions>
<RadioButton Grid.Column="0" Content="Left"/>
<RadioButton Grid.Column="1" HorizontalAlignment="Center" Content="Center"/>
<RadioButton Grid.Column="2" Content="Right"/>
</Grid>
and then on a suitable parent container use the attached property Grid.IsSharedSizeScope="true"
<ListBox Grid.IsSharedSizeScope="True" ItemTemplate={StaticResource RadioButtonTemplate}/>

Related

WPF ListBox Header And Data Alignment

I am trying to align data with the headers in a WPF application. The headers a line up and spaced nicely. However, I cannot get the data items underneath to line up with the headers. Any suggestions?
I have been poking around a bit, but have not found a solution to my problem. I do have to stick with list box as it is part of the requirements. Also, I am new to WPF.
Here is what the output is:
And here is the xaml that I am using:
<Grid Grid.Row="2">
<ListBox ItemsSource="{Binding MyData}">
<ListBox.Template>
<ControlTemplate>
<StackPanel>
<Grid Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" x:Name="ToteNumber"></ColumnDefinition>
<ColumnDefinition Width="*" x:Name="Desription"></ColumnDefinition>
<ColumnDefinition Width="*" x:Name="Time"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Tote Number" HorizontalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="Description" HorizontalAlignment="Center"/>
<TextBlock Grid.Column="2" Text="Time" HorizontalAlignment="Center"/>
</Grid>
<ItemsPresenter></ItemsPresenter>
</StackPanel>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Border BorderThickness="1" BorderBrush="Black">
</Border>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Property1}" HorizontalAlignment="Stretch"/>
<TextBlock Grid.Column="1" Text="{Binding Property2}" HorizontalAlignment="Stretch"/>
<TextBlock Grid.Column="2" Text="{Binding Property3}" HorizontalAlignment="Stretch"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You need to set Grid.IsSharedSizeScope="True" on a parent panel and you need to identify the SharedSizeGroup on each column so it knows which column in your listbox template grid corresponds to which one in your itemtemplate.
Note that I think * width is treated as Auto when you apply Sharedsizegroup.
I use width auto and minwidth instead when I've done something similar.
You may find you need to bind width of each column to some parent measuring grid or calculate minwidth using a converter based on ViewportWidth of the scrollviewer in your listbox.
<Grid Grid.Row="2" Grid.IsSharedSizeScope="True">
<ListBox ItemsSource="{Binding MyData}">
<ListBox.Template>
<ControlTemplate>
<StackPanel>
<Grid Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="A" x:Name="ToteNumber"></ColumnDefinition>
<ColumnDefinition Width="*" SharedSizeGroup="B" x:Name="Desription"></ColumnDefinition>
<ColumnDefinition Width="*" SharedSizeGroup="C" x:Name="Time"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Tote Number" HorizontalAlignment="Center"/>
<TextBlock Grid.Column="1" Text="Description" HorizontalAlignment="Center"/>
<TextBlock Grid.Column="2" Text="Time" HorizontalAlignment="Center"/>
</Grid>
<ItemsPresenter></ItemsPresenter>
</StackPanel>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Border BorderThickness="1" BorderBrush="Black">
</Border>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="A"></ColumnDefinition>
<ColumnDefinition Width="*" SharedSizeGroup="B"></ColumnDefinition>
<ColumnDefinition Width="*" SharedSizeGroup="C"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Property1}" HorizontalAlignment="Stretch"/>
<TextBlock Grid.Column="1" Text="{Binding Property2}" HorizontalAlignment="Stretch"/>
<TextBlock Grid.Column="2" Text="{Binding Property3}" HorizontalAlignment="Stretch"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
As I mentioned, I use a similar technique in some of my own markup. For that I put the headers grid and then the listbox with an itemtemplate in a stackpanel.
<StackPanel>
<Grid>
Headers
<ListBox>
ItemTemplate
</StackPanel>
Sounds like that doesn't suit whatever is driving your requirements though.

ItemsControl/ListBox items exceed available width

I want text in column 3 wrap and have no horizontal scrollbar. Why doesn't this work?
<ItemsControl x:Name="listMessages" ItemsSource="{Binding Messages}" Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column2"/>
<ColumnDefinition Width="*" SharedSizeGroup="Column3"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column4"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Text1" />
<TextBlock Grid.Column="1" Text="Text2" />
<TextBlock Grid.Column="2" Text="Very long text that should wrap to the next line, but it doesn't work" TextWrapping="Wrap"/>
<TextBlock Grid.Column="3" Text="Text4" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Items take more width than is available to ItemsControl. Same problem is with ListBox.
I tried to add ScrollViewer.HorizontalScrollbarVisibility=Disabled both on ItemsControl and Grid, but this doesn't help.
The text will be wrapped if you don't set the SharedSizeGroup property:
<ColumnDefinition Width="*"/>
Text wrapping and shared size groups don't go well together. You may want to specify a fixed MaxWidth for the ColumnDefinition or the TextBlock.

Wrapping itemscontrol items in a form

Currently i have a form with this layout
Label:TextBox
Label:TextBox
.............
I have to change the layout to
Label:TextBox Label:TextBox
Label:TextBox Label:TextBox
............. .............
By vertical wrapping of items.
I have done this before with static items. But the items are in Itemscontrol thanks to the previous coder.
Here is my current code.
<Grid Background="{StaticResource AppWhiteBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="250"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="75"></ColumnDefinition>
</Grid.ColumnDefinitions>
.....................................................................
<StackPanel MaxHeight="350" Orientation="Vertical"
ScrollViewer.VerticalScrollBarVisibility="Disabled" VerticalAlignment="Top"
Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Visibility="{Binding
IsEditClick, Converter={StaticResource InverseBoolToVisibilityConverter}}"
x:Name="ViewPanel" >
<StackPanel.Resources>
<DataTemplate x:Key="ContainerDetailsList">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Style="{StaticResource DetailsItemKey}"
Content="{Binding ItemLabel}">
</Label>
<TextBox Grid.Column="1" x:Name="TextItem" Text="{Binding
OriginalItemValue, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource DetailsItemValue}">
</TextBox>
</Grid>
</DataTemplate>
</StackPanel.Resources>
<ItemsControl x:Name="MainContainerDetails"
Visibility="{Binding DetailsMenuItemViewModel.IsSelected, Converter=
{StaticResource BoolToVisibilityConverter}}"
ITEMSOURCE="{Binding ValueItems, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource DetailsItemTemplateControl}"
ItemTemplate="{StaticResource ContainerDetailsList}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="true" Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
The items are not wrapping... what am i missing?
you should play with MaxWidth Property like this
substitue this:
<ColumnDefinition Width="*" />
with this
<ColumnDefinition Width="*" MaxWidth="100"/>

WP8 - XAML Grid column expanding when text is too long

I have a grid with column definitions.
Whenever the text inside a column cell exceeds the designated width, it shrinks the left hand column down.
Here's an example
And this is my xaml markup
<ItemsControl Name="rfbItems" ItemsSource="{Binding}"
Style="{StaticResource contentItemsControl}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Width="Auto" HorizontalAlignment="Left" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*" />
<ColumnDefinition Width="0.7*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Title}" Style="{StaticResource App_Content_Grid}" TextAlignment="Left" />
<TextBlock Grid.Column="1" Text="{Binding Description}" Style="{StaticResource App_Content_Grid_Subtle}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
How should I restrict this behavior without losing responsiveness in the layout?
Also, if there is a better way to achieve what I'm trying to do here (inside the datatemplate), please feel free to share :)
Try setting margin and horizontal alignment to text boxes as below:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*" />
<ColumnDefinition Width="0.7*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="5" HorizontalAlignment="Stretch" Text="{Binding Title}" Style="{StaticResource App_Content_Grid}" TextAlignment="Left" />
<TextBlock Grid.Column="1" Margin="5" HorizontalAlignment="Stretch" Text="{Binding Description}" Style="{StaticResource App_Content_Grid_Subtle}" />
</Grid>
The Grid doesn't have a limited width unless you give your StackPanel a fixed width. Setting Width="123" should work, HorizontalAlignment="Stretch" might do it as well (untested).
I'm sorry for all your efforts, but I found a solution.
None of the answers worked for me, so feel free to find a fitting solution and I'll accept your answer.
<ItemsControl Name="rfbItems" ItemsSource="{Binding}"
Style="{StaticResource contentItemsControl}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Width="Auto" HorizontalAlignment="Left" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Title}" Style="{StaticResource App_Content_Grid}" TextAlignment="Left" />
<TextBlock Grid.Column="1" Text="{Binding Description}" Style="{StaticResource App_Content_Grid_Subtle}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The first column has a fixed width, that's why the second column can't expand anymore.

List items into a Grid (not GridView)

In my WPF application, I have a collection to which I would like to bind a grid of controls. An example of the desired layout (TL;DR I want this from an ItemsSource):
Desired layout http://imagebin.ca/img/27UTke
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0">FileUploader</Label>
<ComboBox Grid.Row="0" Grid.Column="1" />
<Button Grid.Row="0" Grid.Column="2">Edit</Button>
<Label Grid.Row="1" Grid.Column="0">TextUploader</Label>
<ComboBox Grid.Row="1" Grid.Column="1" />
<Button Grid.Row="1" Grid.Column="2">Edit</Button>
<Label Grid.Row="2" Grid.Column="0">UrlShortener</Label>
<ComboBox Grid.Row="2" Grid.Column="1" />
<Button Grid.Row="2" Grid.Column="2">Edit</Button>
<Label Grid.Row="3" Grid.Column="0">ImageUploader</Label>
<ComboBox Grid.Row="3" Grid.Column="1" />
<Button Grid.Row="3" Grid.Column="2">Edit</Button>
</Grid>
This example is has hardcoded values; I want to bind the collection dynamically, like using a ListView. However, using a ListView with a GridView isn't what I want; I don't need selection, headers, sorting, etc. To the user, the layout is a neatly organized set of options, not a data set in a grid.
I haven't been able to do this binding properly. I've tried using an ItemsControl with a Grid on the outside, but the Grid is ignored:
Failed attempt 1 http://imagebin.ca/img/kTUordk
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding MyData}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl>
<Label Grid.Column="0">Text here</Label>
<ComboBox Grid.Column="1" />
<Button Grid.Column="2">Edit</Button>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
I've also used an ItemsControl with a Grid in the panel, but this creates one Grid per item, which is ugly:
Failed attempt 2 http://imagebin.ca/img/xHo__-JD
<ItemsControl ItemsSource="{Binding Data}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<Label Grid.Column="0" Content="{Binding Features}" />
<ComboBox Grid.Column="1" />
<Button Grid.Column="2">Edit</Button>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
After some research, I discovered the SharedSizeGroup property of column and row grid definitions. I have tried this with the previous attempt; however, the middle column (with width *) does not seem to resize itself to fill the full width of the window:
Failed attempt 3 http://imagebin.ca/img/nEoMJmy
<ItemsControl ItemsSource="{Binding Data}" Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
<ColumnDefinition Width="*" SharedSizeGroup="B" />
<ColumnDefinition Width="Auto" SharedSizeGroup="C" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<Label Grid.Column="0" Content="{Binding Features}" />
<ComboBox Grid.Column="1" />
<Button Grid.Column="2">Edit</Button>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
What is the best way to accomplish the first layout?
John Bowen wrote a blog entry about a pitfall of using * with SharedSizeGroups. Using his suggested workaround, I was able to get the desired layout:
<Grid Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="C" />
</Grid.ColumnDefinitions>
</Grid>
<ItemsControl ItemsSource="{Binding Data}" Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
<ColumnDefinition Width="{Binding ColumnDefinitions[1].Width, ElementName=grid}" />
<ColumnDefinition Width="Auto" SharedSizeGroup="C" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<Label Grid.Column="0" Content="{Binding Features}" />
<ComboBox Grid.Column="1" />
<Button Grid.Column="2">Edit</Button>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Sadly, this seems like a hack; I'm sure there's a better solution out there for accomplishing what I want.

Resources