Wrapping itemscontrol items in a form - wpf

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"/>

Related

Sharing column widths between multiple grids

I have the following XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Header 1" />
<TextBlock Grid.Column="1" Text="Header 2" />
</Grid>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding SomeList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Value1}" />
<TextBox Grid.Column="1" Text="{Binding Value2}" />
<Button Grid.Column="2" Content="Button" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
and I want to achieve something like that:
Header 1 |Header 2 | <-- this is the top grid
------------------------------------------------------
Value 1.1 |Value 1.2 |[Button] |
Value 2.1 |Value 2.2 |[Button] <-- | this is the scroll viewer
Value 3.1 |Value 3.2 |[Button] |
which looks similar to a data grid with the fixed header row. I can't use an actual DataGrid because in the real app "Header 1" and "Header 2" are actually not simple grid text headers but rather interactable elements with quite complex markup. The main question is how to achieve the width synchronization for all three columns? The last column should size itself to the widest button in that column while the first two columns should share the remaining space in 50/50 proportion. It feels like this can be achieved using the SharedSizeGroup property but I cannot figure out how exactly.
I think I figured out how to do it:
<Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Width="{Binding ActualWidth, ElementName=itemsControl}"
HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="ButtonColumn" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Header 1" />
<TextBlock Grid.Column="1" Text="Header 2" />
</Grid>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<ItemsControl Name="itemsControl" ItemsSource="{Binding SomeList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="ButtonColumn" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Value1}" />
<TextBox Grid.Column="1" Text="{Binding Value2}" />
<Button Grid.Column="2" Content="Button" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
Grid.IsSharedSizeScope="True" and SharedSizeGroup="ButtonColumn" synchronize the last columns.
Width="*" splits the remaining space between first two columns in 50/50 proportion.
Width="{Binding ActualWidth, ElementName=itemsControl}" synchronizes the width of the top header grid with the width of the ItemsControl below which can change when the scroll bar is shown or hidden.
HorizontalAlignment="Left" pushes the header grid to the left to align it with the ItemsControl below.

XAML - 2 buttons in one grid column

I have to put 2 buttons in this same row and column on grid
i don't want use margin or vertical position, but i want to their positions is:
on upper than second.
how to simply do that?
i did this by:
<button1 verticalAligment="top" />
<button2 verticalAligment="bottom" />
but how to do that better way?
Try This.
<telerik:RadGridView Name="AppsGridView" AutoGenerateColumns="False" IsReadOnly="True">
<telerik:RadGridView.Columns>
<telerik:GridViewColumn>
<telerik:GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<telerik:RadButton Grid.Row="0" Grid.Column="1" Width="40" Cursor="Hand" Content="Edit" FontSize="14" Background="#FFF2F2F2" CornerRadius="3" verticalAligment="top"/>
<telerik:RadButton Grid.Row="0" Grid.Column="1" Width="50" Cursor="Hand" Content="Delete" FontSize="14" Background="#FFF2F2F2" CornerRadius="3" verticalAligment="bottom"/>
</Grid>
</DataTemplate>
</telerik:GridViewColumn.CellTemplate>
</telerik:GridViewColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
Use Wrappanel as follows
<Wrappanel Orientation="Horizontal"><button1 HorizontalAlignment="Left"/><button2 HorizontalAlignment="Right" /></Wrappanel>

How to use only 1 grid layout for both header and detail with itemscontrol?

Now, when i want to create a table with a header and detail i have to define a columns 2 times for each row. the first row is header and the second row i used itemscontrol to binding data.
below is my sample code.
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource WidthColumn}" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding ListTitle}"/>
<TextBlock Grid.Column="1" Text="{Binding ListDetailTitle}" />
<TextBlock Grid.Column="2" Text="{Binding ListValueTitle}" />
</Grid>
<StackPanel Grid.Row="1">
<ItemsControl ItemsSource ="{Binding Samples}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type parameters:SampleParameters}">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource WidthColumn}" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Position}"/>
<TextBox Grid.Column="1" DataContext="{Binding Name}" Text="{Binding Value}"/>
<Button Grid.Column="2" Name="Button"/>
</Grid>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</StackPanel>
</Grid>
Can it use only 1 time grid layout? or there is another solution to do with?

Radiobutton Even Horizontal Alignment

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}/>

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