Binding SelectedItem from CollectionView - c#

I'm developing my frist app on xamarin-forms, using XamarinForms v4.2, Prism.Dryloc v7.2 and Refit.
I have 3 collectionview on my MenuPage
Food
Drinks
Cart
A web service fills the first two and they work great, I need to select one of each one and I'm trying to binding the selected items to the Cart collection, I'm debugging to understand how it works but at the moment of selection this appear on my Debug Console:
"[0:] Binding: KioscoColab.Models.Menu can not be converted to type 'System.Collections.ObjectModel.ObservableCollection'1[KioscoColab.Models.Menu]
Here is my code:
ViewModel
...
ObservableCollection<Menu> _food;
ObservableCollection<Menu> _drinks;
ObservableCollection<Menu> _cart;
public ObservableCollection<Menu> Food
{
get => _food;
set => SetProperty(ref _food, value);
}
public ObservableCollection<Menu> Drinks
{
get => _drinks;
set => SetProperty(ref _drinks, value);
}
public ObservableCollection<Menu> Cart
{
get => _cart;
set => SetProperty(ref _cart, value);
}
...
public async Task LoadMenu()
{
//Here is my logic for the web service
...
Food = new ObservableCollection<Menu>(food.Content);
Drinks = new ObservableCollection<Menu>(drinks.Content);
Cart = new ObservableCollection<Menu>();
}
...
XamlPage
<!-- CollectionView Food-->
<CollectionView
Grid.Row="1"
Grid.Column="0"
Margin="5"
ItemsSource="{Binding Food}"
SelectedItem="{Binding Cart, Mode=TwoWay}"
SelectionMode="Single"
VerticalScrollBarVisibility="Always">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Grid.Column="0"
FontSize="Medium"
Text="{Binding Description}"
VerticalOptions="Center" />
<Label
Grid.Column="1"
FontSize="Medium"
HorizontalTextAlignment="End"
Text="{Binding Price, StringFormat='{0:C}'}"
VerticalOptions="Center" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<!-- CollectionView Cart -->
<CollectionView
Grid.Row="1"
Grid.Column="1"
Margin="5"
ItemsSource="{Binding Cart}"
VerticalScrollBarVisibility="Always">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Label
Grid.Column="0"
FontSize="18"
Text="{Binding Description}"
VerticalOptions="Center" />
<Label
Grid.Column="1"
FontSize="18"
Text="{Binding Price}"
VerticalOptions="End" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
How can I make the cast? Or what should I do?

Related

Changing Label which is nested inside a CollectionView

In my RecentProductsCV CollectionView, I have two <Label>s named PPriceLabel and PLastPriceLabel:
<CollectionView x:Name="RecentProductsCv" SelectionMode="Single">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2"/>
</CollectionView.ItemsLayout>
<CollectionView.EmptyView>
<Label Text="No Product found." HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
</CollectionView.EmptyView>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Frame CornerRadius="10" HeightRequest="90" WidthRequest="90" Grid.Row="0">
<Image Source="{Binding ProductImage}" Aspect="AspectFit" HeightRequest="90" WidthRequest="90"/>
</Frame>
<Label Text="{Binding ProductName}" TextColor="Black" FontSize="Subtitle" Grid.Row="1"/>
<Label x:Name="PPriceLabel" Text="{Binding ProductPrice, StringFormat='BDT {0}'}" TextColor="#e67e22" FontSize="Caption" Grid.Row="2"/>
<Label x:Name="PLastPriceLabel" Text="{Binding ProductLastPrice, StringFormat='BDT {0}'}" TextDecorations="Strikethrough" FontSize="Micro" Grid.Row="3"/>
<StackLayout Orientation="Horizontal" Grid.Row="4">
<Label Text="{Binding ProductRatings, StringFormat='({0}/5)'}" TextColor="LightGray" FontSize="Caption"/>
<Image Source="ratingStar.png" Aspect="AspectFit" HeightRequest="25" WidthRequest="25"/>
</StackLayout>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
I want to disable PLastPriceLabel if the values of PPriceLabel and PLastPriceLabel are the same.
In your ViewModel, you can add a new property to control whether the PLastPriceLabel is visible or not:
public class myViewModel
{
public bool isAvailable { get; set; }
public string ProductPrice { get; set; }
public string ProductLastPrice { get; set; }
public myViewModel()
{
isAvailable = true;
getData();
}
void getData()
{
if (ProductPrice == ProductLastPrice)
{
isAvailable = false;
}
}
}
In your collectionView, bind the isAvailable to the isVisible property in the Xaml:
<Label x:Name="PLastPriceLabel" IsVisible="{Binding isAvailable}" Text="{Binding ProductLastPrice, StringFormat='BDT {0}'}" TextDecorations="Strikethrough" FontSize="Micro" Grid.Row="3"/>
Then PLastPriceLabel will not be visible when PPriceLabel & PLastPriceLabel value is the same.
Xamarin Community Toolkit has a NotEqualConverter you can use to do this
<Label Text="{Binding ProductLastPrice, StringFormat='BDT {0}'}"
TextDecorations="Strikethrough" FontSize="Micro" Grid.Row="3"
IsVisible="{Binding ProductLastPrice, Converter={StaticResource NotEqualConverter},
ConverterParameter={Binding ProductPrice}}" />

How to have multiple level of binding with ListViews

Here's my problem, I want to have a few ListViews with their ItemsSource attached with binding to SelectedItem of other ListViews.
Here's a picture to show you the interface to give you an overlook :
So I have a "Tours" ListView who's ItemSource is bonded with a ObservableCollection property.
Now I want the "Parties" ListView to be bond with the SelectedItem of the "Tours" ListView.
Afterwards, I want the "Équipes" ListView to be bound with the SelectedItem of the "Parties" ListView.
And so on...
Right now, it is working, but the program crash :
Select a "Tour" from "Tours"
Select a "Partie" from "Parties"
Select a "Équipe" from "Équipes"
Select a "Different "Tour" from "Tours"
Crash
I supposed it was when I change "Tour", the "Équipe" point toward something inexistant.
This is the XAML of the ListViews and the content (the content isn't bond right now) :
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel>
<Label Style="{StaticResource menu}" Content="Tours" />
<ListView Name="lvTours" ItemsSource="{Binding Tours}" SelectionChanged="lvTours_SelectionChanged">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Nom}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
<Label Style="{StaticResource menu}" Content="Parties" />
<ListView Name="lvParties" DataContext="{Binding RelativeSource={RelativeSource Self}}" SelectionChanged="lvParties_SelectionChanged" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Nom}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
<Label Style="{StaticResource menu}" Content="Équipes" />
<ListView Name="lvEquipes" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Nom}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
</StackPanel>
<Label Content="Here's the content..." Grid.Column="1" Margin="30" />
</Grid>
And here's the cs :
using Lama.Logic.Model.Test;
using System.Windows.Controls;
namespace Lama.UI.UC.TournoiControls.StatistiquesControls
{
/// <summary>
/// Interaction logic for Statistiques.xaml
/// </summary>
public partial class StatistiquesUC : UserControl
{
public Tour SelectedTour { get; set; }
public Partie SelectedPartie { get; set; }
public StatistiquesUC()
{
InitializeComponent();
}
private void lvTours_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
lvParties.ItemsSource = ((Tour)lvTours.SelectedItem).Parties;
}
private void lvParties_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
lvEquipes.ItemsSource = ((Partie)lvParties.SelectedItem).Equipes;
}
}
}
So :
"Tours" is a property of ObservableCollection
each "Tour" has a property "Parties" of ObservableCollection
each "Partie" has a property "Equipes" of ObservableCollection
and so on...
Thanks and sorry for my english!
Since you dont want a ViewModel, this is an other approche :
In your xaml does not need to SelectionChanged, just bind itemSource of Lisview Equipe & Partie the parent list view like this :
<Grid DataContext="{Binding YourViewModel}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel>
<Label Style="{StaticResource menu}" Content="Tours" />
<ListView Name="lvTours" ItemsSource="{Binding Tours}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Nom}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
<Label Style="{StaticResource menu}" Content="Parties" />
<ListView Name="lvParties" ItemsSource="{Binding ElementName=lvTours, Path=SelectedItem.Parties}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Nom}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
<Label Style="{StaticResource menu}" Content="Équipes" />
<ListView Name="lvEquipes" ItemsSource="{Binding ElementName=lvParties, Path=SelectedItem.Equipes}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Nom}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
</StackPanel>
<Label Content="Here's the content..." Grid.Column="1" Margin="30" />
</Grid>
Hope it helps

WPF Combobox w/ Observable Collection in Composite Collection

I'm trying to populate a combobox with an observable collection and a header row using a composite collection. The header is there but I can't get the OC objects to populate. I'm just starting to use OC's so might be something basic I'm missing.
Customer class:
public class Customer : ViewModelBaseMain
{
public string CustomerName { get; set; }
public int CustomerId { get; set; }
}
I populate the OC, which is a dependency property, from a datatable (I verified that the OC is being populated correctly):
ObservableCollection<Customer> dpCustomerListOC = new ObservableCollection<Customer>();
foreach (DataRow drow in dpHeaderCustTable.Rows)
{
Customer Customer = new Customer();
Customer.CustomerId = Convert.ToInt32(drow["customer_id"]);
Customer.CustomerName = drow["customer_name"].ToString();
dpCustomerListOC.Add(Customer);
}
In the usercontrol resources, I specify the VM as a static resource:
<local:ReservationViewModel x:Key="ReserveVM"/>
I've tried two different ways from posts I've read.
First way w/ collection in the resources using x:reference:
<ComboBox x:Name="cboCustHeader" Grid.IsSharedSizeScope="True" IsEditable="False"
ItemsSource="{DynamicResource items}">
<ComboBox.Resources>
<CompositeCollection x:Key="items">
<ComboBoxItem IsEnabled="False">
<Border Style="{StaticResource ComboHeaderBorder}">
<Grid Style="{StaticResource ComboHeaderStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
<ColumnDefinition Width="7"/>
<ColumnDefinition SharedSizeGroup="B"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<TextBlock Grid.Column="0" Text="ID"/>
<TextBlock Grid.Column="2" Text="Name"/>
</Grid.Children>
</Grid>
</Border>
</ComboBoxItem>
<CollectionContainer Collection="{Binding Source={x:Reference cboCustHeader}, Path=DataContext.dpCustomerListOC}"/>
</CompositeCollection>
</ComboBox.Resources>
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
<ColumnDefinition Width="7"/>
<ColumnDefinition SharedSizeGroup="B"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<TextBlock Text="{Binding Path=CustomerId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="{Binding Path=CustomerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid.Children>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Second way specifying the source:
<ComboBox x:Name="cboCustHeader" Grid.IsSharedSizeScope="True">
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem IsEnabled="False">
<Border Style="{StaticResource ComboHeaderBorder}">
<Grid Style="{StaticResource ComboHeaderStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
<ColumnDefinition Width="7"/>
<ColumnDefinition SharedSizeGroup="B"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<TextBlock Grid.Column="0" Text="ID"/>
<TextBlock Grid.Column="2" Text="Name"/>
</Grid.Children>
</Grid>
</Border>
</ComboBoxItem>
<CollectionContainer Collection="{Binding Path=dpCustomerListOC, Source={StaticResource ReserveVM}}"/>
</CompositeCollection>
</ComboBox.ItemsSource>
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
<ColumnDefinition Width="7"/>
<ColumnDefinition SharedSizeGroup="B"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<TextBlock Grid.Column="0" Text="{Binding Path=CustomerId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Column="2" Text="{Binding Path=CustomerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid.Children>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
Add a public property exposing the collection on your view model:
public ObservableCollection<Customer> DpCustomerListOC
{
get { return dpCustomerListOC; }
}
And bind the combo's ItemsSource to it:
<ComboBox x:Name="cboCustHeader" Grid.IsSharedSizeScope="True">
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem IsEnabled="False">
<Border Style="{StaticResource ComboHeaderBorder}">
<Grid Style="{StaticResource ComboHeaderStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
<ColumnDefinition Width="7"/>
<ColumnDefinition SharedSizeGroup="B"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<TextBlock Grid.Column="0" Text="ID"/>
<TextBlock Grid.Column="2" Text="Name"/>
</Grid.Children>
</Grid>
</Border>
</ComboBoxItem>
<CollectionContainer Collection="{Binding Path=DpCustomerListOC, Source={StaticResource ReserveVM}}"/>
</CompositeCollection>
</ComboBox.ItemsSource>
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
<ColumnDefinition Width="7"/>
<ColumnDefinition SharedSizeGroup="B"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<TextBlock Grid.Column="0" Text="{Binding Path=CustomerId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Column="2" Text="{Binding Path=CustomerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid.Children>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Make sure the collection is populated in the constructor.
It seems like you are missing to NotifyPropertyChange. When working with ComboBoxs I usually just do something like this:
<ComboBox ItemsSource="{Binding Customers, Mode=OneWay}"
SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"> </ComboBox>
Then in your class:
public type Customers
{
get{return _Customers}
set{_SelectedCustomer = value;
NotifyPropertyChanged("Customers");}
}
public type SelectedCustomer
{
get{return _SelectedCustomer;}
set{_SelectedCustomer = value;
NotifyPropertyChanged("SelectedCustomer")}
}
The syntax may be off a little bit but something like this should populate the ComboBox.

Binding items using multiple selection mode ListBox?

Here is my problem i need to solve.
My data content is in DemoList class:
NOTICE: DemoHeader object contains a ObservableCollection of DemoItem objects, and DemoList object contains ObservableCollection of DemoHeader objects
public enum Type
{
article,
product,
material
}
public class DemoHeader
{
private ObservableCollection<DemoItem> _items;
public ObservableCollection<DemoItem> Items
{
get { return _items; }
set { _items = value; }
}
public DemoHeader(string document)
{
this._salesOrder = document;
_items = new ObservableCollection<DemoItem>();
}
private string _salesOrder;
public string SalesOrder
{
get { return _salesOrder; }
set { _salesOrder = value; }
}
}
public class DemoItem
{
public DemoItem(string name, Type type)
{
this._name = name;
this._type = type;
}
private Type _type;
public Type Type
{
get { return _type; }
set { _type = value; }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
public class DemoList : ObservableCollection<DemoHeader>//, ICollectionView
{
public DemoList()
{
DemoHeader dd = new DemoHeader("Doc-1");
dd.Items.Add(new DemoItem("T-1", Type.article));
dd.Items.Add(new DemoItem("M-1", Type.material));
DemoHeader dd2 = new DemoHeader("Doc-2");
dd2.Items.Add(new DemoItem("P-1", Type.product));
dd2.Items.Add(new DemoItem("P-2", Type.product));
this.Add(dd);
this.Add(dd2);
}
}
XAML:
NOTICE: I have 4 CollectionViewSource for each ListBox.
<Window x:Class="WuZet.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:WuZet"
Title="WuZet" WindowStartupLocation="CenterScreen" ResizeMode="CanResize" Loaded="window_loaded" Background="#ECE9D8" WindowStyle="ToolWindow" Icon="/WuZet;component/Images/ksi_ikona.ico" Topmost="True" WindowState="Maximized" SizeToContent="WidthAndHeight">
<Window.Resources>
<CollectionViewSource x:Key="list" Source="{Binding}"></CollectionViewSource>
<CollectionViewSource x:Key="wares" Source="{Binding Source={StaticResource list}, Path=Items}" Filter="wareFilter"></CollectionViewSource>
<CollectionViewSource x:Key="materials" Source="{Binding Source={StaticResource list}, Path=Items}" Filter="materialFilter"></CollectionViewSource>
<CollectionViewSource x:Key="products" Source="{Binding Source={StaticResource list}, Path=Items}" Filter="productFilter"></CollectionViewSource>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="200"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="200"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0" Grid.ColumnSpan="2" Margin="5,5,5,5">
<TextBox/>
<Button Content="ok" Margin="0,5,0,0" HorizontalAlignment="Stretch" Height="30" Width="150" Click="Button_Click"/>
</StackPanel>
<StackPanel Grid.RowSpan="2" Grid.Column="2">
<ListBox Name="orders" IsEnabled="{Binding ElementName=check, Path=IsChecked}" Margin="85,5,85,5" Height="70" ItemsSource="{Binding Source={StaticResource list}}" DisplayMemberPath="SalesOrder"/>
<CheckBox Name="check" HorizontalAlignment="Center" Content="Wybierz zamówienie" IsChecked="False"/>
</StackPanel>
<GroupBox Header="Wares" Grid.Row="2" Grid.Column="0">
<ListBox Name="lbWares" ItemsSource="{Binding Source={StaticResource wares}}" >
<ListBox.ItemTemplate>
<DataTemplate>
<!--<StackPanel Orientation="Horizontal">-->
<TextBlock Text="{Binding Path=Name}"></TextBlock>
<!--<TextBlock Text="{Binding ZaE_TwrKod}" />
<TextBlock Text=", " />
<TextBlock Text="{Binding ZaE_Ilosc}" />
<TextBlock Text=", " />
<TextBlock Text="{Binding ZaE_TwrNazwa}" />-->
<!--</StackPanel>-->
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</GroupBox>
<GroupBox Header="Materials" Grid.Row="2" Grid.Column="1">
<ListBox Name="lbMaterials" ItemsSource="{Binding Source={StaticResource materials}}">
<ListBox.ItemTemplate>
<DataTemplate>
<!--<StackPanel Orientation="Horizontal">-->
<TextBlock Text="{Binding Path=Name}"/>
<!--<TextBlock Text=", " />
<TextBlock Text="{Binding ZaE_Ilosc}" />
<TextBlock Text=", " />
<TextBlock Text="{Binding ZaE_TwrNazwa}" />-->
<!--</StackPanel>-->
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</GroupBox>
<GroupBox Header="Products" Grid.Row="2" Grid.Column="2">
<ListBox Name="lbProducts" ItemsSource="{Binding Source={StaticResource products}}">
<ListBox.ItemTemplate>
<DataTemplate>
<!--<StackPanel Orientation="Horizontal">-->
<TextBlock Text="{Binding Path=Name}"/>
<!--<TextBlock Text=", " />
<TextBlock Text="{Binding ZaE_Ilosc}" />
<TextBlock Text=", " />
<TextBlock Text="{Binding ZaE_TwrNazwa}" />
</StackPanel>-->
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</GroupBox>
</Window>
DemoList object is binding to CollectionViewList x:Key=list.
Here is my buisiness logic i need to implement:
If checkbox is marked i need to return selected ListBoxItem to the
corresponding containers [wares, products, materials] - this logic is
working
If checkbox is unmarked i need to return ALL items
[ObservableCollection] of ALL headers to the corresponding
containers [wares, products, materials]
I'm stuck right here, can anyone suggest me a solution?
--- 2013-11-04 20:38
Sry for misunderstanding, and for my bad english.
I uploaded some screen to be more clear.
http://imgur.com/UowQrRP
As you see on the screen i need to implement behavior for checkbox.
When it is unchecked each DemoItem object must be display in one of 3 containers.
Each container is bind to CollectionViewSource.

How to set tooltip with many rows for each (dynamic) listbox item in Silverlight

I would like to set in Silverlight for each item in a ListBox a tooltip with many rows.
In XAML i have a listbox and a button:
<ListBox Height="100" HorizontalAlignment="Left" Margin="24,136,0,0" Name="listBox1" VerticalAlignment="Top" Width="109" ItemsSource="{Binding}">
<Button Content="Add" Name="button_add" VerticalAlignment="Top" Width="118" Click="add_Click">
in c#
private void button_add_Click(object sender, RoutedEventArgs e)
{
ObservableCollection<Person> obs1 = new ObservableCollection<Person>();
obs1.Add(new Person(){Name="Name1", Age=1});
obs1.Add(new Person(){Name="Name2", Age=2});
listBox1.ItemsSource = obs1;
// This Line of Code MUST NOT BE USED!! listBox1.DisplayMemberPath = "Name";
}
public class Person
{
public String Name { get; set; }
public int Age { get; set; }
public override string ToString()
{
return Name;
}
}
I would like to show for each item the Age as my tooltip.
Edit: Ok, this is the Solution for showing only AGE as tooltip. That is one Line/Row.
<ListBox Height="100" HorizontalAlignment="Left" Margin="24,136,0,0" Name="listBox1" VerticalAlignment="Top" Width="109" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" ToolTipService.ToolTip="{Binding Age}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But what if i want to show a Tooltip with 2 Lines? something like:
Name: Name1
Age: 1
Edit: 3 rows, 2 columns. i also added public String Comment { set; get; } to class Person
<ListBox Height="100" HorizontalAlignment="Left" Margin="24,136,0,0" Name="listBox1" VerticalAlignment="Top" Width="109" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<ToolTipService.ToolTip>
<ToolTip>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="250"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Name: " Grid.Row="0" Grid.Column="0" />
<TextBlock Text="{Binding Name}" Grid.Row="0" Grid.Column="1"/>
<TextBlock Text="Age: " Grid.Row="1" Grid.Column="0"/>
<TextBlock Text="{Binding Age}" Grid.Row="1" Grid.Column="1"/>
<TextBlock Text="Comment: " Grid.Row="2" Grid.Column="0"/>
<TextBlock Text="{Binding Comment}" Grid.Row="2" Grid.Column="1" TextWrapping="Wrap" />
</Grid>
</ToolTip>
</ToolTipService.ToolTip>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But there is stil a problem. The comment can be short or long, so i would like to make the ROWS/LINES/SPACE for Comment to be variable or else Text is cut off.
You can use any controls for tooltip content:
<ToolTipService.ToolTip>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Age}" />
</StackPanel>
</ToolTipService.ToolTip>
Other possibility would be to use a converter, that returns the Name and Age separated by \r\n.

Categories

Resources