Listbox of comboboxes and binding them WPF - c#

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>

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>

UserControl with a combobox and a listView

I have a Usercontrol that contains a ListView, Add Button and a ComboBox. The intention is that when a user clicks Add the selected item in the ComboBox is added to the ListView.
This functionality works fine, however it would be great if the item in the ComboBox was removed list as duplicates aren't allowed in the ListView. Currently I am handling this in the ViewModel, but that means I have to implement the same code for each instance of the UserControl
Does anyone have a good idea how to implement a generic solution for this problem?
<UserControl>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListView x:Name="ListView"
ItemsSource="{x:Bind ListViewItemsSource}"
SelectedItem="{x:Bind ListViewSelectedItem, Mode=TwoWay}"
ItemTemplate="{x:Bind ListViewItemTemplate}"
Style="{x:Bind ListViewStyle}"
Margin="{StaticResource MediumBottomMargin}"
Visibility="{x:Bind ListViewVisibility, Mode=TwoWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<uwptoolkit:WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
<StackPanel Grid.Row="1"
Orientation="Horizontal">
<ComboBox x:Name="ComboBox"
Style="{StaticResource StandardComboStyleFixedWidth}"
ItemsSource="{x:Bind ComboBoxItemsSource, Mode=OneWay}"
SelectedItem="{x:Bind ComboBoxSelectedItem, Mode=TwoWay}"
DisplayMemberPath="{x:Bind ComboBoxDisplayMemberPath}"
PlaceholderText="{x:Bind ComboBoxPlaceholderText}"
BorderBrush="{x:Bind ComboBoxBorderBrush, Mode=TwoWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ComboBox>
<Button x:Name="AddButton"
Style="{StaticResource AddButtonStyle}"
Click="AddButton_Click"
IsEnabled="{x:Bind AddButtonIsEnabled, Mode=TwoWay}"/>
</StackPanel>
</Grid>
</UserControl>
EDIT:
I should add that I didn't create this class, I have inherited it and am looking to improve it. I will implement the style changes suggested.
What I mean by code behind is this:
<uc:ListTagControl
ComboBoxItemsSource="{x:Bind _viewModel.TypeItems, Mode=TwoWay}"
ComboBoxSelectedItem="{x:Bind _viewModel.SafetyType, Mode=TwoWay}"
ComboBoxDisplayMemberPath="Type"
ListViewSelectedItem="{x:Bind _viewModel.SelectedListViewItem, Mode=TwoWay}"
ListViewItemsSource="{x:Bind _viewModel.Safeties, Mode=TwoWay}"
AddButtonOnClick="{x:Bind _viewModel.AddType}"
AddButtonIsEnabled="True" />
In the ViewModel it will then do this, to remove the item from the combobox:
TypeItems.Remove(TypeItems
.Where(i => i.Id == _Safety.SafetyType.Id).Single());
I want to move this as a generic implementation into the xaml.cs

Display multiple column data in C# WPF

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>

Different DataContext in ItemsControl

My Code looks like this:
<ItemsControl ItemsSource="{Binding Path=MTMngRoot.MTManager.MTCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding Path=Name}" ToolTip="Name" Controls:TextBoxHelper.Watermark="Name" Grid.Column="0"/>
<ComboBox SelectedItem="{Binding Path=DefaultCT}" Grid.Column="1">
<ComboBoxItem>Item 1</ComboBoxItem>
<ComboBoxItem>Item 2</ComboBoxItem>
</ComboBox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This code works correctly. But now I want to bind the Itemssource from the ComboBox. My Problem is now, the Path of the Items that should be bind to the ComboBox is completly different. The Path looks like this: CTMngRoot.CTManager.CTCollection.Name. Any ideas how I can do this?
You walk up to the control with the correct DataContext in these cases.
{Binding DataContext.CTMngRoot.CTManager.CTCollection,
RelativeSource={RelativeSource AncestorType=ItemsControl}}

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(?)

Categories

Resources