Display multiple column data in C# WPF - c#

I need to display two columns of dataset; first column is the Checkbox items and second column would be just a list<string>
I am able to build first column (grid.column=0) using Listbox with Checkbox in XAML as:
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ListBox x:Name="Listitems" Grid.Column="0" SelectionMode="Multiple" ItemsSource="{Binding MonthlyResults}" >
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding logdate}" IsChecked="{Binding Checked ,Mode=TwoWay}"
Click="CheckBox_Click"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
User interface is displayed correctly as:
For the second column, I thought of using a ListView(grid.colum=1) and updated the above XAML as:
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListBox x:Name="Listitems" Grid.Column="0" SelectionMode="Multiple" ItemsSource="{Binding MonthlyResults}" >
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding logdate}" IsChecked="{Binding Checked ,Mode=TwoWay}"
Click="CheckBox_Click"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListView Grid.Column="1" Name="CatNames" FontSize="13" SelectionMode="Extended"
ItemsSource="{Binding Path=OFMCategoriesNames}" IsSynchronizedWithCurrentItem="False" >
</ListView>
</Grid>
But the user interface is messed up. Both columns have their own scrollbars.
How to display the columns in the same listbox ?
*************Update based on the answer provided***************
I updated the XAML as:
<Grid Grid.Row="0">
<ListBox x:Name="Listitems" SelectionMode="Multiple" ItemsSource="{Binding MonthlyResults}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="A1"/>
<ColumnDefinition Width="*" SharedSizeGroup="A2"/>
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0" Content="{Binding logdate}" IsChecked="{Binding Checked ,Mode=TwoWay}" Click="CheckBox_Click"/>
<ListView Grid.Column="1" Name="CatNames" FontSize="13" SelectionMode="Extended"
ItemsSource="{Binding MeasureMethod}" IsSynchronizedWithCurrentItem="False" >
</ListView>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Even after adding "sharedsizegroup", the columns are not aligned properly..

You can either use a Grid view inside the ListView like
<ListView.View>
<GridView>
....
</GridView>
</ListView.View>
or you can use a grid inside your template
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
<ColumnDefinition SharedSizeGroup="B"/>
<ColumnDefinition SharedSizeGroup="C"/>
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0"/>
<TextBlock Grid.Column="1"/>
<TextBlock Grid.Column="2"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>

Related

Pass informations between two ColumnDefinition?

I have a problem to understand how can i show details of a selected cells into a second ColumnDefinition. The Details-Propertys are into a Observable Dictionary with KeyValuePair setup.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<DataGrid ItemsSource="{Binding Persons.Values}" AutoGenerateColumns="False" Grid.Column="0">
<DataGrid.Columns>
<DataGridTemplateColumn SortMemberPath="Key.Name" Header="K1 Regler" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Border Background="Azure">
<Grid>
<Label Foreground="Black" Content="{Binding Path=Key.Name}" Width="Auto" HorizontalContentAlignment="Center"/>
</Grid>
</Border>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
How can i pass the Data between the ColumnDefinitions if i selected one of the Datagrid cells?
Have you tried binding to the DataGrid element's SelectedItem?
Check the TextBlock below, you can replace it with DataGrid and bind to ItemsSource if that's what you are looking for.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<DataGrid x:Name="PersonsGrid" ItemsSource="{Binding Persons.Values}" AutoGenerateColumns="False" Grid.Column="0">
<DataGrid.Columns>
<DataGridTemplateColumn SortMemberPath="Key.Name" Header="K1 Regler" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Border Background="Azure">
<Grid>
<Label Foreground="Black" Content="{Binding Path=Key.Name}" Width="Auto" HorizontalContentAlignment="Center"/>
</Grid>
</Border>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<TextBlock Text="{Binding ElementName=PersonsGrid, Path=SelectedItem}" Grid.Column="1"/>
</Grid>

Align controls correctly when using ItemsControl in WPF

Can someone tell me how to align and resize controls correctly when using the ItemsControl.
I want to have a description on the left and a TextBox on the right for multiple fields which are defined in an ObservableCollection to end up with something like:
First Name: [FirstNameTextBox]
Last Name: [LastNameTextBox]
Date of Birth: [DobTextBox]
but instead I'm getting this:
First Name: [FirstNameTextBox]
Last Name: [LastNameTextBox]
Date of Birth: [DobTextBox]
I want all the textbox to be aligned based on the largest <TextBlock>. If this was done directly in a <Grid> control, it would be straight forward as all controls are directly in the grid and you would just have the following columns definition defined
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
I thought I could use the SharedSizeGroup property in the <Grid> but it still doesn't resize correctly. Instead it only displays the <TextBlock> stretch across the <Grid>.
Here's my code:
<Grid Grid.IsSharedSizeScope="True" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Labels" />
<ColumnDefinition Width="*" SharedSizeGroup="InputControls" />
</Grid.ColumnDefinitions>
<ItemsControl Grid.Row="1" ItemsSource="{Binding SelectedTemplate.Fields}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels"/>
<ColumnDefinition SharedSizeGroup="InputControls"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}" Grid.Column="0" Margin="5"
VerticalAlignment="Center" Background="Red" />
<TextBox Text="{Binding Path=Value}" Grid.Column="1" Margin="5"
VerticalAlignment="Center" Background="Blue" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Any idea how I can resolve this?
Thanks.
UPDATE1: I cannot get this to work as I need it to. This is what I've got so far:
<Grid Grid.Row="1" Background="Purple">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="Overall" />
</Grid.ColumnDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
<ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding SelectedTemplate.Fields}"
Background="Yellow"
Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Background="Green">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels"/>
<ColumnDefinition SharedSizeGroup="InputControls"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center"/>
<TextBox Text="{Binding Path=Name}"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
This ends up displaying my layout this way:
As you can see, my TextBox are correctly aligned based on the largest TextBlock but my ItemsControls is not stretched all the way across. I guess that makes sense as it is within the same grid where the ColumnDefinitions are defined.
Now, if I move the ColumnDefinitions' out this grid to the outer grid and remove all instances ofGrid.IsSharedSizeScope`, I guess the following:
Which once again is closer to what I need as my ItemsControl is now stretching all the way as I've set its Grid.ColumnSpan="2" and my TextBox are still aligned to the TextBlock and are stretching all the way across but the problem now is that the TextBlock should be smaller as the Column is set to Auto but they appear to behave as if the column was set to * and I guess I'm losing the purpose of using IsSharedSizeScope since it has been removed.
Now if I add IsSharedSizeScope="True" to the outer grid, I get the following result:
Again, this is close to what I want as my ItemsControl is stretched, my textboxes are also stretch but they are no longer aligned to the largest TextBlock.
Finally, if I add Grid.IsSharedSizeScope="True" to ItemsControl as originally suggested by #mm8,
<Grid Grid.Row="1" Background="Purple" Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
<ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.ColumnSpan="2" >
<ItemsControl ItemsSource="{Binding SelectedTemplate.Fields}"
Background="Yellow"
Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Background="Green">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels"/>
<ColumnDefinition SharedSizeGroup="InputControls"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center"/>
<TextBox Text="{Binding Path=Name}"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
<!--<TextBlock Text="Invoice Number" Grid.Column="0" Margin="5" VerticalAlignment="Center"/>
<TextBox Text="InvoiceNumber" Grid.Column="1" Margin="5" VerticalAlignment="Center"/>-->
</Grid>
I get the following:
Which brings me back to square one, though the definitions are different?
I need to achieve the following:
What am I doing wrong??
Thanks.
Try to set the Grid.IsSharedSizeScope property of the ItemsControl itself:
<ItemsControl Grid.Row="1" ItemsSource="{Binding SelectedBarcodeTemplate.Fields}"
Grid.IsSharedSizeScope="True">
Synchronizing the width of elements in an ItemsControl: https://joshsmithonwpf.wordpress.com/2008/09/06/synchronizing-the-width-of-elements-in-an-itemscontrol/
I eventually found the answer in the following article: WPF Tutorial - Grid Panel under the section: "How to share the width of a column over multiple grids".
As per article:
Columns and rows that participate in size-sharing do not respect Star sizing. In the size-sharing scenario, Star sizing is treated as Auto. Since TextWrapping on TextBlocks within an SharedSize column does not work you can exclude your last column from the shared size. This often helps to resolve the problem.
So my final XAML looks like this:
<Grid Grid.Row="1" Background="Purple" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
<ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
</Grid.ColumnDefinitions>
</Grid>
<ItemsControl ItemsSource="{Binding SelectedBarcodeTemplate.Fields}"
Background="Yellow"
Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Background="Green" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Labels"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center"/>
<TextBox Text="{Binding Path=Name}"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
And the outcome now finally looks correct:
Hope this helps others!

How to bind Observablecollection<T> with combobox in wpf

I am trying to bind Observablecollection<T> with ComboBox. ComboBox having Datatemplete
<ComboBox Width="150" Margin="20,0,0,5" Name="cbSelection" Height="20"
BorderThickness="2" BorderBrush="Black"
SelectedIndex="0" DataContext="{Binding AdComboBox}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding XPath=LOC, Mode=OneWay}" Margin="5,0,5,0"/>
<TextBlock Grid.Column="1" Text="{Binding XPath=PUB, Mode=OneWay}" Margin="0,0,5,0"/>
<TextBlock Grid.Column="2" Text="{Binding XPath=EDI, Mode=OneWay}" Margin="0,0,5,0"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
but not get the data in ComboBox
what going wrong
thanks in advance
Use the ItemsSource of the ComboBox to point to the ObservableCollection<T>. Also: Use Path, not XPath which is used for binding to XML documents.
<ComboBox Width="150" Margin="20,0,0,5" Name="cbSelection" Height="20"
BorderThickness="2" BorderBrush="Black"
ItemsSource="{Binding AdComboBox}"
SelectedIndex="0">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="{Binding Path=LOC, Mode=OneWay}"
Margin="5,0,5,0"/>
<TextBlock Grid.Column="1"
Text="{Binding Path=PUB, Mode=OneWay}"
Margin="0,0,5,0"/>
<TextBlock Grid.Column="2"
Text="{Binding Path=EDI, Mode=OneWay}"
Margin="0,0,5,0"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Side note: you might want to rename the collection to something more functional instead of AdComboBox. E.g., Ads Because it is not a ComboBox but it is a collection of Ads(?)

Controls vertical alignment with grid on the left and right

I have a custom listbox with a label and a checkbox in each row. I would like to have the label on the far left and the checkbox on the far right.
approach:
<ListBox x:Name="lbFieldsreq" HorizontalAlignment="Left" Height="100" Margin="513,232,0,0" VerticalAlignment="Top" Width="100">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Content="{Binding name, Mode=OneWay}" Grid.Column="0" HorizontalAlignment="Left" />
<Label Grid.Column="1" HorizontalAlignment="Center" /> <!--Empty column -->
<CheckBox IsChecked="{Binding ticked ,Mode=OneWay}" Grid.Column="2" HorizontalAlignment="Right" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
current look:
Thx
Your XAML is mostly fine. All you really need to do is to set the ListBox.HorizontalContentAlignment property to "Stretch". This basically forces each item in the collection to stretch to fill with entire Width of the related ListBoxItem. However, you could improve this further by setting the Grid.IsSharedSizeScope Attached Property to True. Setting this in conjunction with the SharedSizeGroup property enables us to ensure that the column Widths of each column of the DataTemplate are the same. Try this:
<ListBox x:Name="lbFieldsreq" HorizontalAlignment="Left" Height="100" ItemsSource="{Binding Items}" VerticalAlignment="Top" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid ShowGridLines="True" Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelColumn" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="CheckBoxColumn" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}" Grid.Column="0" HorizontalAlignment="Left" />
<!--Empty column -->
<Label Grid.Column="1" HorizontalAlignment="Center" />
<CheckBox Grid.Column="2" IsChecked="{Binding ticked, Mode=OneWay}" HorizontalAlignment="Right" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Listbox of comboboxes and binding them WPF

I have a situation where i have a listbox of comboboxes , mainly it binds to a bridge entity so the object contains foreign keys . What i need to do is that i need to bind the display of the combos to the respective entities and their value members to the foreign key values in the bridge entity that i bind the listbox to.
the code i have now is :
<ListBox Name="lstServices" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="2" DataContext="{Binding ElementName=wndMain,Path=DataContext}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ComboBox Name="cmbService" SelectedIndex="0" DisplayMemberPath="Name" SelectedValuePath="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=FK_ServiceID}" ItemsSource="{Binding Path=AllServices}" Grid.Column="0"></ComboBox>
<ComboBox Name="cmbService_Role" Margin="2,0,0,0" SelectedValuePath="{Binding Path=FK_ServiceRoleID}" DisplayMemberPath="Name" ItemsSource="{Binding Path=AllService_Roles}" Grid.Column="1"></ComboBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I could manage to display the values that i needed but since the List Item context changed i can't get to the listbox itemSource .
Any help is appreciated
Bishoy
I got it :D , here is how it should go
<ListBox Name="lstServices" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalContentAlignment="Stretch" ItemsSource="{Binding MemberServices}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ComboBox Name="cmbService" SelectedValue="{Binding FK_ServiceID,Mode=TwoWay}" ItemsSource="{Binding ElementName=wndMain, Path=DataContext.AllServices,Mode=OneTime}" SelectedValuePath="ID" DisplayMemberPath="Name" Grid.Column="0" ></ComboBox>
<ComboBox Name="cmbService_Role" SelectedValue="{Binding FK_ServiceRoleID,Mode=TwoWay}" ItemsSource="{Binding ElementName=wndMain, Path=DataContext.AllService_Roles,Mode=OneTime}" SelectedValuePath="ID" DisplayMemberPath="Name" Grid.Column="1" Margin="2,0,0,0"></ComboBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>

Categories

Resources