ListBox inside ListBox and selectedItem / Events - silverlight

I have now been stuck at this for some time so I though to ask the experts here.
First the XAML:
<ListBox Grid.Column="0" Tap="Some_Tap" SelectionChanged="Some_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<!-- the panel which covers a complete list item -->
<StackPanel Orientation="Vertical">
<!-- start and end time for the travel route-->
<Grid HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- some textblock items, removed to keep this simple -->
</Grid>
<!-- list box for images -->
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" ItemsSource="{Binding Thumbs}" HorizontalAlignment="Center" Margin="0,10,0,50">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<Image Source="{Binding Image}" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding Text}" HorizontalAlignment="Center" FontWeight="{Binding FontWeightForText}">
<TextBlock.Foreground>
<SolidColorBrush Color="{StaticResource PhoneForegroundColor}"/>
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So as you can see from the XAML I have a ListBox inside the data template of another ListBox. I have Tap & SelectionChanged events wired.
Problem:
I can't click on the area covered by the inner list box, the tap or selection changed events for the outer list box are not fired for the outerlistbox.
I could wire tap and selection changed events for the inner listbox as well, but then how would I know which item in the outerlistbox this innerlistbox belongs to, selectedindex.
help ??
-A

If you don't need items selection in the list, use ItemsControl instead (for inner list in this situation)

Just set the inner ListBox control IsEnabled = false and the Tap events of the outer will start to execute!

Related

How To Organize ItemsPanel Layout?

I have the code below which I want to display a series of buttons horizontally with an image and text label, and below that row of buttons one label for the entire button group. What I currently have displays the buttons in a row, but the group label displays in the same row to the left of the buttons. I'm probably doing this wrong, but I'm impressed that I got this far. I've tried putting the Child ItemsPanel in a StackPanel, but then it shows no buttons - it seems to loose contact with the collection from the parent window. Is there an easy way to connect this collection and organize the label below the buttons? I'm thinking my next try is to collect the data from the parent in the child's code-behind and build an ItemsSource which I will then connect to the ItemTemplate, but I don't really know how to do that either.
Parent window snippet:
<User_Controls:ToolbarGroup GroupLabel="Group 1">
<User_Controls:ImageButton ButtonText="Test 1"/>
<User_Controls:ImageButton ButtonText="Test 2"/>
<User_Controls:ImageButton ButtonText="Test 3"/>
</User_Controls:ToolbarGroup>
Child window code:
<ItemsControl x:Class="Fiducia_WPF.User_Controls.ToolbarGroup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:User_Controls="clr-namespace:Fiducia_WPF.User_Controls"
mc:Ignorable="d"
Loaded="ItemsControl_Loaded"
d:DesignHeight="170" d:DesignWidth="320">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Height="170" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<User_Controls:ImageButton ButtonText="Temp"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<Label Name="lblGroupTitle" Grid.Row="1" Grid.Column="0" Content="Group X" FontSize="16" FontWeight="Bold" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Visible" />
</ItemsControl>
You should create a ControlTemplate for your ItemsControl:
<ItemsControl x:Class="Fiducia_WPF.User_Controls.ToolbarGroup" ...>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<StackPanel>
<ItemsPresenter/>
<Label x:Name="lblGroupTitle" Content="Group X" ... />
</StackPanel>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Height="170" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<User_Controls:ImageButton ButtonText="Temp"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Setting the Content of the lblGroupTitle Label may probably better be done by binding it to a property of the ToolbarGroup control:
<Label Content="{Binding GroupTitle,
RelativeSource={RelativeSource AncestorType=User_Controls:ToolbarGroup}}" ... />
I'd just use a straight up Grid:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" ... />
<Button Grid.Row="0" Grid.Column="1" ... />
<Button Grid.Row="0" Grid.Column="2" ... />
<Label Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" />
</Grid>

user control inside tabitem does not change values

I have a TabContorl and I am adding tabitem dynamically. I have bind datatemplate to some viewmodel and view is loaded as defined in datatemplate.
<DataTemplate DataType="{x:Type viewmodels:ItemViewModel}">
<views:CustomerOrderView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:InvoiceGeneratorViewModel}">
<views:InvoiceGenerator/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:OrderDetailsViewModel}">
<views:OrderDetailsView/>
</DataTemplate>
if i use controls directly in customerorderview then it works fine. It means if i switch the tab all values are loaded accordingly but does not work properly when if i use another usercontrol insite customerview user control. I have created once user control have one textbox, button and a popup contorl. When i click on button the popup opens and remains even if swich the tab. If textbox value is change the value is also changed for all tabs. It looks one view is serving all the tabs. I could not understand how to handle it.
Below is the user control which i am using inside customer
<UserControl x:Class="OrderManagement.Views.ProductSelectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="txtProduct" Grid.Row="0" Grid.Column="0"/>
<Button x:Name="btnSearch" Content="S" Click="OnSearchClick" Grid.Row="0" Grid.Column="1" Margin="5"/>
<Popup x:Name="popup" PlacementTarget="{Binding ElementName=btnSearch}" Placement="Bottom"
Width="300" Height="300" Margin="5">
<Border BorderBrush="Black" BorderThickness="2" Background="AliceBlue">
<Grid >
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
<DataGrid x:Name="dataGrid" AutoGenerateColumns="False" Grid.Row="0" Grid.ColumnSpan="2"
IsReadOnly="False" CanUserAddRows="False" CanUserDeleteRows="False">
<DataGrid.Columns>
<DataGridCheckBoxColumn Binding="{Binding IsChecked}" IsReadOnly="False"/>
<DataGridTextColumn Header="Product Name" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Quantity In Stock" Binding="{Binding QuantityInStock}"/>
</DataGrid.Columns>
</DataGrid>
<WrapPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right">
<Button Content="OK" Click="OnOKClick" Width="80"/>
<Button Content="Cancel" Click="OnCancelClick" Width="80" Margin="20,0,0,0"/>
</WrapPanel>
</Grid>
</Border>
</Popup>
</Grid>
</UserControl>
Tabcontrol virtualize the data as per its datacontext but popup and text value in productselection control remains the same for all tabs. opens the popup but it remains for all the tab.
Let me know if how it can be done or what is the mistake i am doing

ListBox scrolling with variable height

I have a problem with ListBox scrolling. Everytime I have more items than can be shown on screen and I try to scroll through the list it automatically snaps back to the top. I found this can be fixed by setting a fixed height to the ListBox.
However, I need to add items to the list dynamically and hence the height changes.
The Listbox is in the second row of a grid nested in a PivotItem.
How can I either set the height of the Listbox dynamically with XAML or achieve a scrolling effect that does not always snap to the top and hence prevents me from reading/editing items on the bottom?
Here is the XAML:
<Grid x:Name="LayoutRoot">
...
<controls:Pivot Title="Malts">
<controls:PivotItem Header="Gravity" Name="GravityPivot">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid> some more controls in row 0</Grid>
<Grid
Grid.Row="1">
<ListBox
VerticalAlignment="Stretch"
ItemsSource="{Binding ItemList}"
Padding="10,10,0,10"
ItemContainerStyle="{StaticResource ListBoxItemStyle}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock
Style="{StaticResource PhoneTextExtraLargeStyle}"
Text="{Binding Name}"
VerticalAlignment="Bottom"/>
<StackPanel>
<StackPanel
Orientation="Horizontal" >
<TextBlock
Text="{Binding Amount, Converter={StaticResource WeightConverter},StringFormat=' {0:f2}'}"
Margin="10,0,5,0"
Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock
Text="{Binding ., Converter={StaticResource UnitExtension}, ConverterParameter='Weight'}"
Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
</StackPanel>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem
Header="Edit"
Command="{Binding ElementName=MaltList, Path=DataContext.EditCommand}"
CommandParameter="{Binding}"/>
<toolkit:MenuItem
Header="Remove"
Command="{Binding ElementName=MaltList, Path=DataContext.RemoveCommand}"
CommandParameter="{Binding}"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</controls:PivotItem>
Thank you!
Try this, should fix you up;
<ListBox>
<!-- You want this part... -->
<ListBox.Template>
<ControlTemplate>
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ListBox.Template>
</ListBox>

Silverlight - Applying Converters within Templates

I am currently updating the template of a ListPicker. In particular, I'm trying to style the contents of the full mode popup. This information appears to be defined in the following code:
<Popup x:Name="FullModePopup">
<Border Background="{StaticResource PhoneChromeBrush}">
<!-- Popup.Child should always be a Border -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Content="{TemplateBinding FullModeHeader}"
Foreground="{StaticResource PhoneForegroundBrush}"
FontFamily="{StaticResource PhoneFontFamilySemiBold}"
FontSize="{StaticResource PhoneFontSizeNormal}"
HorizontalAlignment="Left" Margin="24 12 0 0"/>
<ListBox x:Name="FullModeSelector" Grid.Row="1"
FontSize="{TemplateBinding FontSize}"
Margin="{StaticResource PhoneMargin}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
<!-- Ensures all containers will be available during the Loaded event -->
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</Border>
</Popup>
My challenge is, I need to trim the text of each item bound in this popup list. More importantly, I need to do this with a converter. Is this even possible? How do I use a converter in this template? Traditionally, I've used something like:
<TextBlock Text="{Binding Path=Name, Converter={StaticResource myConverter}}" />
How do I apply a Converter to the items in the Popup of my ListPicker?
Thank you!
Is this what you are looking for?
Basically overriding the itemtemplate, putting in a textblock and apply your converter to the binding.
Like this
<ListBox ItemsSource="{StaticResource customers}" Width="350" Margin="0,5,0,10">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Padding="5,0,5,0"
Text="{Binding FirstName, Converter={StaticResource yourConverter}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Here is the msdn documentation
HTH

How keep drop down opened in silverlights ComboBox?

I use ComboBox control as popup. Item for my ComboBox is Grid. There is TreeView control and two Buttons in grid. Items of TreeView are CheckBoxes.
When I click on Buttons or CheckBoxes drop down keeps opened, but when I click on other part of grid drop down i closed.
Is there any way to keep it opened until I click outside of ComboBox?
I have looked a lot in Google, but haven't found anything.
<UserControl.Resources>
<common:HierarchicalDataTemplate x:Key="HierarchicalDataTemplate_AddDivision" ItemsSource="{Binding DivisionIDs}">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Click="CheckBox_Click" />
<TextBlock Text="{Binding ToDisplay}"/>
</StackPanel>
</common:HierarchicalDataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.90*"/>
<RowDefinition Height="0.10*"/>
</Grid.RowDefinitions>
<controls:TreeView Height="250" x:Name="itemsToShow" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="230"
Grid.ColumnSpan="2" ItemTemplate="{StaticResource HierarchicalDataTemplate_AddDivision}" SelectedItemChanged="itemsToShow_SelectedItemChanged" />
<Button Margin="28,0,22,5" Content="Ok" Grid.Row="1" d:LayoutOverrides="Height" Click="OkButton_Click"/>
<Button Margin="23,0,27,5" Content="Cancel" Grid.Column="1" Grid.Row="1" d:LayoutOverrides="Height" Click="CancelButton_Click"/>
</Grid>
And this is ComboBox
<ComboBox Grid.Row="1" Width="100" Height="20" HorizontalAlignment="Left" VerticalAlignment="Top" >
<ComboBox.ItemTemplate>
<DataTemplate>
<my1:ShowDivisions x:Name="ShowDivs" Loaded="ShowDivs_Loaded" ParentComboBox="{Binding ElementName=addStr2}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
It sounds like your buttons are not filling all the space in the dropdown part of the ComboBox.
In that case you just need to have a a clickable object behind the buttons to eat any stray mouse clicks:
Try a rectangle with the background set to Transparent (not just a colour with 0 alpha value, as that is not clickable).
(Make sure the rectangle has IsHittestVisible set as well).

Resources