Wpf Listbox doesn't bind to multiple items - c#

the Xaml looks like this:
<ListBox Name="lbEurInsuredType" HorizontalContentAlignment="Stretch" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
<!-- <ColumnDefinition Width="20"></ColumnDefinition>-->
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}"></TextBlock>
<TextBox Text="{Binding Uw}"></TextBox>
<!-- <TextBox Text="{Binding Partner}"></TextBox>-->
</Grid>
</DataTemplate></ListBox.ItemTemplate>
</ListBox>
then in my code behind I have :
public DefaultSettings()
{
InitializeComponent();
List<EurItem> items = new List<EurItem>
{
new EurItem() { Title = "Couple", Uw = 190m, Partner = 170m },
new EurItem() { Title = "Family", Uw = 180m, Partner = 160m }
};
lbEurInsuredType.ItemsSource = items;
}
What happens is that If I Only have the TextBlock in the xaml, then the title shows in the listbox, as soon as I start to introduce other members, then it displays the last item that has been bound and looses all the others.

This is unnecessary because you are already directly setting it in your code behind.
ItemsSource="{Binding}"
Also, you are not setting any Grid.Column definitions on your succeeding elements. So they are overlapping each other.
You might want something like this
<Grid Margin="0,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition Width="20"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}"></TextBlock>
<TextBox Text="{Binding Uw}" Grid.Column="1"></TextBox>
<TextBox Text="{Binding Partner}" Grid.Column="2"></TextBox>
</Grid>

You're placing several controls in a Grid with several columns. By default, each item you place inside a Grid is shown in the first row and first column.
Since you're not telling the controls otherwise, all your controls are being added to the first row and column, overlapping each other... So only the last control is shown.
You need to use Grid.Column to specify which column should each control be placed in.
<ListBox Name="lbEurInsuredType" HorizontalContentAlignment="Stretch" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"></ColumnDefinition>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition Width="20"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}"></TextBlock>
<TextBox Text="{Binding Uw}" Grid.Column="1"></TextBox>
<TextBox Text="{Binding Partner}" Grid.Column="2"></TextBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Related

WPF ListBox Layout (dynamic column width considering all rows at once)

Is there a way to make sure that the Width="auto" property considers the Width of all elements in a list instead of calculating it individually for every row in the list?
<ListBox x:Name="listBox" HorizontalContentAlignment="Stretch" DockPanel.Dock="Top">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" />
<TextBlock Grid.Column="1" Text="{Binding Value}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I tried this, but as the length of the Name is different for each column, the Width of the Name column of every row is different. Thus the second column starts at a different x position.
You can use SharedSizeGroup property in the ColumnDefinition like this:
<ColumnDefinition SharedSizeGroup="A"/>
Also have a look at this: Grid Size Sharing in WPF.

ComboBox items in full-mode and normal-mode

I want to show an accent color chooser like what is built-in in the system.
When It's in full mode, I want it to appear as tiles with available colors, and when it appears as a drop-down list, I want it to appear as a little square and color name next to it.
The problem is that I don't know how to set two templates for full-mode and drop-down mode.
<ComboBox SelectionChanged="AccentColor_SelectionChanged">
<ComboBoxItem>
<ComboBoxItem.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Fill="Yellow" Width="20" Height="20"/>
<TextBlock Grid.Column="1" Text="Yellow" />
</Grid>
</ComboBoxItem.Content>
</ComboBoxItem>
<ComboBoxItem>
<ComboBoxItem.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Fill="Blue" Width="20" Height="20"/>
<TextBlock Grid.Column="1" Text="Blue" />
</Grid>
</ComboBoxItem.Content>
</ComboBoxItem>
</ComboBox>
This works only for drop down mode. How can I achieve it? (It's a Windows PHone Runtime app).
normally in wp8 when number of items in a dropdownlist becomes more than 5 items it will automatically turns to a full screen mode.else it will show in just a drop list..
In listpicker there is a property call ExpantionMode..try that or following link will help you..
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868195.aspx
try this..just edit as per your requirement.
I have just pasted my code.
<wpToolkit:ListPicker Name="cmbCountry" Background="#FFF9E2" Foreground="#333333" Grid.Column="0" ExpansionMode="FullScreenOnly" ItemsSource="{Binding Countries}" SelectionChanged="cmbCountry_SelectionChanged_1">
<wpToolkit:ListPicker.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding CountryName}" FontSize="20"></TextBlock>
</DataTemplate>
</wpToolkit:ListPicker.ItemTemplate>
<wpToolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<Border BorderBrush="#FFF9E2" BorderThickness="0,0,0,3">
<StackPanel Orientation="Horizontal" Width="425">
<TextBlock Text="{Binding CountryName}" FontSize="35"></TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</wpToolkit:ListPicker.FullModeItemTemplate>

How to Bind Data to Multi-Column ListBox WP8.1

I'm new to the whole data binding thing with XAML for WP8.1. I've been searching on the internet and I can't seem to find a straight-forward answer to my problem.
I have a ListBox control on my page with 3 columns. What I need to do is fill each column with it's respective data.
I have a class that defines a "CompleteStation" which is made up of 3 strings (StationName, Distance, and GasPrice)
This is the XAML code for the ListBox... How am I able to pass the ListBox a CompleteStation (3 strings) and have it separate each string into the correct column?
This is my XAML code below. In my main class, I'm just adding a CommpleteStation item to the ListBox.
Also, do I need to reference the CompleteStation class in the XAML code? If yes, how do I do this?
<ListBox Name="listBoxStations" FontSize="20" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Width="480" Background="#e6e6e6" Margin="0,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Station}"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Distance}"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding Price}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Thanks!
-Johan
Lets say your CompleteStation is an ObservableCollection which implements NotifyPropertyChanged, Then XAML should be as follows
<ListBox Name="listBoxStations" ItemSource={Binding CompleteStation} FontSize="20" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Width="480" Background="#e6e6e6" Margin="0,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Station}"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Distance}"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding Price}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Your Model:
public sealed class CommpleteStation
{
public string Station{get;set;}
public string Distance{get;set;}
public string Price{get;set;}
}
Your ViewModel:
public sealed class MyViewModel
{
public ObservableCollection<CommpleteStation> CommpleteStations{get;private set;}
public MyViewModel()
{
CommpleteStations = new ObservableCollection<CommpleteStation>();
CommpleteStations.Add(new CommpleteStation{Station="One", Distance="15",Price="130"};
}
}
Then,
IN codebehind for your UI, the "View", you instantiate your ViewModel and set it as the DataContext for your View.
public MyView()
{
this.DataContext = new MyViewModel();
}

Design Xaml grid with height = 100% and minimum row height size

Here's the problem. I have a grid with some data written in xaml:
<ItemsControl x:Name="ItemsControl" ItemsSource="{Binding Path=MyObjectCollection, UpdateSourceTrigger = PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="27"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MaxHeight="75" MinHeight="30"></RowDefinition>
</Grid.RowDefinitions>
<Label Name="LabelNumber" Content="{Binding ObjectID}" Grid.Column="0" Style="{StaticResource MyStyleLabel}" />
<control:FocusMeterControl x:Name="HorizontalFocusMeterControl" Value="{Binding ObjectProperty}" Height="Auto" Grid.Column="1" />
<Button Name="RemoveObject" Content="-" Grid.Column="2" Margin="5,0,0,0" Click="ButtonBase_OnClick" Tag="{Binding Point}" Style="{StaticResource MyStyleButton}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
As you can see I'm creating a new grid for each member in my "MyObjectCollection". Ideally I think I should just create one row instead since this would make my next problem - the real problem easier.
However, I have not found any good way to do this in xaml if even possible. Is this possible without populating the collection manually from c# and setting a row-property in my objects manually in order to do something like this
<Label Name="LabelNumber" Grid.Row="{Binding ManuallyCalculatedRowID}" ... />
My primary problem is that I would like the grid/rows to all be equally high and if possible fill out the parent window. If the parent window is way too large MaxHeight should apply and I would just like some empty space below.
The parent control is a Windows Form ElementHost if that makes any difference.
Please let me know if you need any additional info.
To make all rows of equal hight we can use ItemsPanelTemplate and set it to UniformGrid that will take care of equal sizing problem:
<ItemsControl x:Name="ItemsControl" ItemsSource="{Binding Path=MyObjectCollection, UpdateSourceTrigger = PropertyChanged}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="27"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Label Name="LabelNumber" Content="{Binding ObjectID}" Grid.Column="0" Style="{StaticResource MyStyleLabel}" />
<control:FocusMeterControl x:Name="HorizontalFocusMeterControl" Value="{Binding ObjectProperty}" Height="Auto" Grid.Column="1" />
<Button Name="RemoveObject" Content="-" Grid.Column="2" Margin="5,0,0,0" Click="ButtonBase_OnClick" Tag="{Binding Point}" Style="{StaticResource MyStyleButton}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Note that I removed row definition in ItemTemplate to lift vertical size restrictions for items. Not sure if that answers your question but that can be good starting point on the road to solution.

Programmatically create listbox with datatemplate and binding data

I'm working on Windows store app. Is there any way to programmatically create a listbox with datatemplate and then to bind data to datatemplate items?
I have created this listbox but now I need to create the same listbox programmatically because I need to create listboxes dynamically(count of listboxes is dynamic),
The second problem: I need to bind text to listbox datatemplate items. Does someone know something to recommend to me?
XAML:
<ListBox x:Name="lbTransitNow" ItemsSource="{Binding MyDataBusStationsCurrent}" SelectionChanged="LbTransitNow_OnSelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate >
<StackPanel>
<Grid x:Name="gridTodayBtn">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="tbTransitStart" Grid.Column="0" Text="{Binding Lines_departure_date}" />
<TextBlock x:Name="tbTransitEnd" Grid.Column="1" Text="{Binding Lines_arrival_date}" />
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code:
foreach (var routs in cpStationsrs.RoutesList)
{
foreach (var lines in routs.LinesList)
{
foreach (var stops in lines.StopsList)
{
_myDataBusStationsChoosen.Add(new BindingData
{
Lines_stops_nameSub = stops.Name,
Lines_stops_timeSub = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, stops.Time.Hour, stops.Time.Minute, 0).ToString("dd.MM.yyyy -- HH:mm"),
Lines_nameSub = lines.Name,
...
});
}
}
}
OnPropertyChanged("MyDataBusStationsChoosen");
As far as I know, there is no way to create a DataTemplate programmatically in WinRT. However, if I understand your question correctly, you can reuse the same template for all listboxes... So you could just declare the template in the resources and reference it in each ListBox.
<Page.Resources>
<DataTemplate x:Key="myItemTemplate">
<StackPanel>
<Grid x:Name="gridTodayBtn">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="tbTransitStart" Grid.Column="0" Text="{Binding Lines_departure_date}" />
<TextBlock x:Name="tbTransitEnd" Grid.Column="1" Text="{Binding Lines_arrival_date}" />
</Grid>
</StackPanel>
</DataTemplate>
</Page.Resources>
Then, in code:
var listBox = new ListBox { ItemTemplate = (DataTemplate)Resources["myItemTemplate"] }

Categories