How to bind Observablecollection<T> with combobox in wpf - c#

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

Related

WPF DataTemplate - Access Property of Parent object

I am customizing the presentation using the HeaderTemplate of a UI item. I would like to access a property of the parent item in the DataTemplate:
<dxa:AccordionItem Header="{Binding SelectedComponents.Count}" Tag="Test" HighlightOnHover="False" HighlightOnPress="False" Margin="0,0,13,0">
<dxa:AccordionItem.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="1"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding RelativeSource=Tag}" VerticalAlignment="Center" />
<TextBlock Text="{Binding}" Grid.Column="2" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Rectangle Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" VerticalAlignment="Center" Fill="DimGray" Height="1"/>
</Grid>
</DataTemplate>
</dxa:AccordionItem.HeaderTemplate>
</dxa:AccordionItem>
Basically, I would like to display the Tag property in the DataTemplate.
I have tried:
Text="{Binding RelativeSource=Tag}"
Text="{Binding Path=Tag}"
Text="{Binding ElementName=Tag}"
but nothing seems to work.
I managed to obtain the neccessary binding using the following method:
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type dxa:AccordionItem}}, Path=Tag}"

UWP - ListView Issue, I can't add my search to the list

I have to use a list.
I'm trying to add my searched data to the view list
and it's crashing again and again.
i thing the issue is in list view
Thank you.
Error:
System.Exception: 'Catastrophic failure (Exception from HRESULT:
0x8000FFFF (E_UNEXPECTED))'
XML:
<ListView x:Name="listView" Grid.ColumnSpan="5" Grid.RowSpan="5" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Top" Height="421" Width="711" Margin="0,93,0,0" Grid.Column="1">
<ListView.HeaderTemplate>
<DataTemplate>
<Grid Padding="12" Background="{ThemeResource SystemBaseLowColor}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Name" Style="{ThemeResource CaptionTextBlockStyle}"/>
<TextBlock Grid.Column="1" Text="Publisher" Style="{ThemeResource CaptionTextBlockStyle}"/>
<TextBlock Grid.Column="2" Text="PublishDate" Style="{ThemeResource CaptionTextBlockStyle}"/>
<TextBlock Grid.Column="3" Text="Quantity" Style="{ThemeResource CaptionTextBlockStyle}"/>
<TextBlock Grid.Column="4" Text="Category" Style="{ThemeResource CaptionTextBlockStyle}"/>
<TextBlock Grid.Column="5" Text="Price" Style="{ThemeResource CaptionTextBlockStyle}"/>
</Grid>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate x:Name="TableDataTemplate">
<Grid Height="48" AutomationProperties.Name="{Binding Name}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="nameTbx" Grid.Column="1" VerticalAlignment="Center" Text="{Binding Name}" />
<TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{Binding model.Publisher}"/>
<TextBlock Grid.Column="3" VerticalAlignment="Center" Text="{Binding model.PublishDate}"/>
<TextBlock Grid.Column="4" VerticalAlignment="Center" Text="{Binding model.Quantity}"/>
<TextBlock Grid.Column="5" VerticalAlignment="Center" Text="{Binding model.Category}"/>
<TextBlock Grid.Column="6" VerticalAlignment="Center" Text="{Binding model.Price}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
c#:
{
public MainPage()
{
this.InitializeComponent();
listView.ItemsSource = BookLib.ItemCollection.Items;
}
private void searchTbx_TextChanged(object sender, TextChangedEventArgs e)
{
var match = BookLib.ItemCollection.Items.Find(x => x.Name.ToLower() == searchTbx.Text.ToLower());
if (match != null)
{
listView.Items.Add(match.Name);
}
}
please help me to slove this issue
You set the ItemsSource to BookLib.ItemCollection.Items in the constructor, means that, all the elements of BookLib.ItemCollection.Items are now items of that listView.
So, in the TextChanged event, aren't you trying to add the same Item which is already in the listView?
That's why your app is crashing.
Solution:
Remove this line from the constructor:
listView.ItemsSource = BookLib.ItemCollection.Items;
You didn't mention the ViewModel you are using for the listview. I am assuming It's like this:
public class Book
{
public string Name { get; set; }
public string Publisher { get; set; }
………
………
………
}
Then you should mention the Data type in the ItemTemplate of your listView like this:
<ListView.ItemTemplate>
<DataTemplate x:Name="TableDataTemplate" x:DataType="Book">
<Grid …………
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
this should solve your problem.
Note:
If you want to let the user search through the BookLib.ItemCollection.Items, consider using an AutoSuggestBox.

Dividing listbox into several columns with headers

I'm trying to divide a listbox into several columns, so that I add an item by calling Listbox.items.add(item); and it will display with different properties in different columns. Here is my code so far:
<ListBox Name="listbox1" HorizontalContentAlignment="Stretch" Padding="2">
<ListBox.ItemTemplate>
<DataTemplate DataType="local:ScheduledEvent">
<Grid Margin="0 5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="3 0 3 0" FontFamily="Helvetica" FontSize="18" Text="{Binding WorldRank}"/>
<TextBlock Grid.Column="1" Text="{Binding Name}"/>
<TextBlock Grid.Column="2" Text="{Binding Surname}"/>
<TextBlock Grid.Column="3" Text="{Binding Age}"/>
<TextBlock Grid.Column="4" Text="{Binding Country}"/>
<TextBlock Grid.Column="5" Text="{Binding GraduationYear}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

.NET 4.x WPF ComboBox Databinding SelectedIndex not working

I'm updating my project from .NET Framework 3.5 to .NET Framework 4.5.1. Everything works, except my databinding to a ComboBox. The ComboBox is part of a Itemscontrol. The XAML code:
<ItemsControl x:Name="AfmetingenLijst" BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}" BorderThickness="0" VerticalContentAlignment="Bottom" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="5,5,5,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Lengte}" Tag="{Binding LID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="1" Text="{Binding Breedte}" Tag="{Binding BID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="2" Text="{Binding Hoogte}" Tag="{Binding HID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="3" Text="{Binding Naam}" Margin="5,5,5,5" />
<ComboBox Grid.Column="4" ItemsSource="{Binding Path=items}" SelectedIndex="{Binding geselecteerdProduct}" SelectedValuePath="Code" DisplayMemberPath = "Naam" SelectionChanged="UpdateList" Height="25" HorizontalAlignment="Stretch" VerticalAlignment="Center"></ComboBox>
<Button Tag="{Binding ID}" Grid.Column="5" Margin="5,5,5,5" Content="{Binding Title}" Click="Afmeting_handler" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
In C# a list is filled with the databinding values:
afm = new List<Afmeting>();
if (afm.Count == 0)
{
afm.Add(new Afmeting() { ID = "+", LID = "L+", BID = "B+", HID = "H+", Title = "+", items = items });
afm[afm.Count - 1].geselecteerdProduct = 0;
afmetingen_counter++;
}
AfmetingenLijst.ItemsSource = afm;
The items in the ComboBox exists, I can select them by mouse. But by default SelectedIndex = -1. But in the list "geselecteerdProduct" (the databinding to SelectedIndex) is set to 0.
In .NET 3.5 it is working perfect, but in 4.x SelectedIndex and the value in "afm" is automatically set to -1.
Items is not empty, there are +- 5 items in the list.
Can someone help me?
I think this is a bug for WPF.
When ComboBox is nested in ItemsControl, and set SelectedIndex and SelectedValuePath at the same time, ComboBox's OnSelectionChanged will be fired tiwce at initialize, but SelectionChanged only once.
WPF ComboBox SelectedIndex debug:
To solve the problem is simple, just remove SelectedValuePath from the ComboBox.
XAML:
<ItemsControl x:Name="AfmetingenLijst" BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}" BorderThickness="0" VerticalContentAlignment="Bottom" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="5,5,5,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Lengte}" Tag="{Binding LID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="1" Text="{Binding Breedte}" Tag="{Binding BID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="2" Text="{Binding Hoogte}" Tag="{Binding HID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="3" Text="{Binding Naam}" Margin="5,5,5,5" />
<ComboBox Grid.Column="4"
ItemsSource="{Binding Path=items}"
SelectedIndex="{Binding geselecteerdProduct}"
DisplayMemberPath = "Naam"
SelectionChanged="UpdateList"
Height="25"
HorizontalAlignment="Stretch"
VerticalAlignment="Center">
</ComboBox>
<Button Tag="{Binding ID}" Grid.Column="5" Margin="5,5,5,5" Content="{Binding Title}" Click="Afmeting_handler" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Windows 8 XAML ListView Header not same size

Currently having an issue where the header of my ListView is larger than my ListView Items, so the header doesn't line up properly. I could use a margin on the header as a hack to fix it, but surely there's a proper way to fix this?
<DataTemplate x:Key="HeaderTemplate" >
<Grid Height="36" Background="#99999999" Margin="0,0,5,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Uid="Name" TextWrapping="Wrap" HorizontalAlignment="Left" Text="Project" Grid.Column="0" Style="{StaticResource BodyTextBlockStyle}" />
<TextBlock x:Uid="Qty" TextWrapping="Wrap" HorizontalAlignment="Left" Text="Qty" Grid.Column="1" Style="{StaticResource BodyTextBlockStyle}" />
<TextBlock x:Uid="SubTotal" TextWrapping="Wrap" HorizontalAlignment="Left" Text="Sub Total" Grid.Column="2" Style="{StaticResource BodyTextBlockStyle}" />
<TextBlock x:Uid="Total" TextWrapping="Wrap" HorizontalAlignment="Left" Text="Total" Grid.Column="3" Style="{StaticResource BodyTextBlockStyle}" />
</Grid>
</DataTemplate>
// ...
<ListView x:Name="CartGridView" ItemsSource="{Binding CartItmes}" HeaderTemplate="{StaticResource HeaderTemplate}"
Grid.Row="1" VerticalAlignment="Stretch" Width="auto" ItemContainerStyle="{StaticResource SimpleListViewItemStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="auto" Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Style="{StaticResource BodyTextBlockStyle}" HorizontalAlignment="Left"
Text="{Binding Name, Mode=TwoWay}"/>
<TextBlock Grid.Column="1" Style="{StaticResource BodyTextBlockStyle}" HorizontalAlignment="Center"
Text="{Binding Qty, Mode=TwoWay}"/>
<TextBlock Grid.Column="2" Style="{StaticResource BodyTextBlockStyle}" HorizontalAlignment="Left"
Text="{Binding SubTotal, Mode=TwoWay}"/>
<TextBlock Grid.Column="3" Style="{StaticResource BodyTextBlockStyle}" HorizontalAlignment="Center"
Text="{Binding Total, Mode=TwoWay}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Add the following to your ListView definition
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>

Categories

Resources