Silverlight - Applying Converters within Templates - silverlight

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

Related

Cannot associate CarouselNavigator with CarouselPanel when CarouselPanel is a child element within CarouselItemsControl ItemsPanelTemplate

i have xaml layout as shown below
<DockPanel Grid.Row="1" Grid.ColumnSpan="2">
<dxca:CarouselItemsControl x:Name="carouselItemsControl" ItemsSource="{Binding ImageList}" DockPanel.Dock="Top">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<dxca:CarouselPanel x:Name="carousel" AttractorPointIndex="2" IsRepeat="True" PathSizingMode="Proportional" FirstVisibleItemIndex="0" Height="Auto" ItemSize="180,120" IsAutoSizeItem="True" VisibleItemCount="5" ActiveItemIndex="1" AnimationTime="500" IsInvertedDirection="True" PathVisible="False">
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas>
<Image Source="{Binding Data.Data}" Width="480" Height="320" Margin="10"/>
<TextBlock Canvas.Left="100" Canvas.Top="10" Text="{Binding Identifier}" FontSize="12" FontWeight="Bold"></TextBlock>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
</dxca:CarouselItemsControl>
<dxca:CarouselNavigator DockPanel.Dock="Bottom" Carousel="< TODO : BINDING EXPRESSION TO BIND TO CarouselPanel>" Width="300" Height="40" />
</DockPanel>
How do i bind the CarouselNavigator to the carousel object in the carousel property using xaml only?
Just use the CarouselItemsControl.Carousel property for this purpose:
<dxca:CarouselNavigator Carousel="{Binding Path=Carousel, ElementName=carouselItemsControl}" />

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>

Rendering templates preformances

I created a propertyGrid like.
I used an Item control which uses a viewmodel object.
The VM object has the property to be display and its relevant DataTemplates.
Everything wosrk fine. My Property grid actually act like the VS property grid
My problem is that every time the use changes the selected object (which lead to changes in the property grid) its took to much time (depends on the amount of the selected object properties). I figured out that the reason for the bad performances is the templates loading and rendering.
so I thought that I may solve this issues by creating real controls for each object, and not just uses templates. (Create buttons and text box for each property) this will solve the loading time, I hope..
1- is there any way to creates real controls (in code) using data templates?
2- is there any other way to improve the performances of my Property grid?
The main code for the propGrid is attached to this post
Thanks, Leon
CODE:
<DataTemplate x:Key="gridItemsControl" >
<Grid Visibility="{Binding Visibility}">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="60" MaxWidth="350" Width="{Binding Source={StaticResource firstCulWidth},Path=Width,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource widthToGridLenConverter}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderBrush="#ff333333" BorderThickness="0.5" Grid.ColumnSpan="2"
Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter},ConverterParameter=Category}">
<StackPanel Orientation="Horizontal" Background="#FFA9BFD4" Height="25">
<Expander Template="{StaticResource SimpleExpanderTemp}" ExpandDirection="Left" IsExpanded="{Binding IsExpanded, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Margin="3,0,5,0"/>
<Label Content="{Binding Path=CategoryName,Converter={StaticResource propertyNameToDiplayNameConverter}}" FontSize="12" Foreground="White" VerticalAlignment="Top" />
</StackPanel>
</Border>
<Border Grid.Column="0" BorderBrush="#ff333333" BorderThickness="0.5"
Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}">
<Label Margin="5,0,0,0" Content="{Binding Path=DisplayName,Converter={StaticResource propertyNameToDiplayNameConverter}}"/>
</Border>
<GridSplitter Grid.Row="0" Grid.Column="0" Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}" HorizontalAlignment="Right" Width="4" Background="Transparent"/>
<Border Grid.Column="1" BorderBrush="#ff333333" BorderThickness="0.5"
Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}">
<ContentPresenter Grid.Column="1" Margin="10,1,10,1" HorizontalAlignment="Left"
ContentTemplate="{Binding Path=InlineTemplate}" />
</Border>
</Grid>
</DataTemplate>
Update: Here is the container
<ItemsControl Name="propsDataGrid" ItemsSource="{Binding Properties}" ItemTemplate ="{StaticResource gridItemsControl}">
<ItemsControl.ContextMenu>
<ContextMenu>
<MenuItem Header="Close all expanders" Click="MenuItem_Click" Visibility="{Binding IsAlphaBeticSort,Converter={StaticResource boolToVisConverter},ConverterParameter=VisForFalse}"></MenuItem>
<MenuItem Header="Expand all" Name="mnExpandeAll" Click="mnExpandeAll_Click" Visibility="{Binding IsAlphaBeticSort,Converter={StaticResource boolToVisConverter},ConverterParameter=VisForFalse}"></MenuItem>
</ContextMenu>
</ItemsControl.ContextMenu>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!--<ItemsControl.ItemTemplate>
<DataTemplate >
<Grid Visibility="{Binding Visibility}">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="60" MaxWidth="350" Width="{Binding Source={StaticResource firstCulWidth},Path=Width,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource widthToGridLenConverter}}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderBrush="#ff333333" BorderThickness="0.5" Grid.ColumnSpan="2"
Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter},ConverterParameter=Category}">
<StackPanel Orientation="Horizontal" Background="#FFA9BFD4" Height="25">
<Expander Template="{StaticResource SimpleExpanderTemp}" ExpandDirection="Left" IsExpanded="{Binding IsExpanded, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Margin="3,0,5,0"/>
<Label Content="{Binding Path=CategoryName,Converter={StaticResource propertyNameToDiplayNameConverter}}" FontSize="12" Foreground="White" VerticalAlignment="Top" />
</StackPanel>
</Border>
<Border Grid.Column="0" BorderBrush="#ff333333" BorderThickness="0.5"
Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}">
<Label Margin="5,0,0,0" Content="{Binding Path=DisplayName,Converter={StaticResource propertyNameToDiplayNameConverter}}"/>
</Border>
<GridSplitter Grid.Row="0" Grid.Column="0" Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}" HorizontalAlignment="Right" Width="4" Background="Transparent"/>
<Border Grid.Column="1" BorderBrush="#ff333333" BorderThickness="0.5"
Visibility ="{Binding IsCategoryItem,Converter={StaticResource isCategoryItemToVisibilityConverter}}">
<ContentPresenter Grid.Column="1" Margin="10,1,10,1" HorizontalAlignment="Left"
ContentTemplate="{Binding Path=InlineTemplate}" />
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>-->
</ItemsControl>
DataTemplates create "real controls" there is no gain in doing something manually which is done automatically using templates, the only thing you should worry about is virtualization (so that the controls for properties not in view are not created) and how your templates are wired up so that their creation is not triggered needlessly.
(By the way, the way you create the grid, setting its width, looks like it might be redundant, you probably can just share the size.)
To make an ItemsControl virtualize the items you need to:
Set the ItemsPanel to a VirtualizingStackPanel
Have a control template which contains a ScrollViewer around the ItemsPresenter where the VirtualizingStackPanel will be.
Set ScrollViewer.CanContentScroll to true to enable scrolling by item which allows for virtualization.
e.g.
<ItemsControl ItemsSource="{Binding Items}"
ScrollViewer.CanContentScroll="True">
<ItemsControl.Template>
<ControlTemplate>
<Border Name="Bd" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true"
Padding="1">
<ScrollViewer Padding="{TemplateBinding Padding}" Focusable="false">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- ... -->
</ItemsControl>
If this is still too slow you could make the whole ItemsControl part of a template which applies per type as presumably the contents of this grid are dependent on the type of the item, thus a different grid should only be created if the item-type changes, also you might be able to cache the resulting templates as well (i never tried doing that though).

How to show a divider between items in a ListBox?

I am using a ListBox control in a Windows Phone 7 application, and I would like to show a divider/line between the list rows.
I have not been able to find any information about this, although many (not wp7) ListBox examples seem to have a divider.
Got inspired by NestorArturo and found out about the Border control.
It is very easy to wrap your ItemTemplate content in a Border control and specify the BorderThickness and BorderBrush. I went this way, because it doesn't require changes to my Grid in the ItemTemplate.
The Border control is described here: http://www.silverlightshow.net/items/Using-the-Border-control-in-Silverlight-2-Beta-1-.aspx.
Below you can see how I use it:
<ListBox Background="White" ItemsSource="{Binding Mode=OneWay, Path=MyPath}" Name="listName" SelectionChanged="listName_SelectionChanged">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
here --> <Border BorderThickness="0,10,0,10" BorderBrush="Black">
<Grid Width="auto" HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="48" />
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" FontSize="36" FontWeight="Bold" Grid.Column="0" Foreground="Black" Text="{Binding Path=Title}" Name="title"/>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Right" Grid.Column="1" Foreground="Black" Text="{Binding Path=Location}" Name="location"/>
<Image VerticalAlignment="Center" Grid.Column="2" Width="48" Height="48" Source="ApplicationIcon.jpg"/>
</Grid>
and here --> </Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You can either change the ListBoxItem template, or, an easier approach is to change your ItemTemplate, You can simply add a divider within your ItemTemplate as follows:
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<!-- your content goes here ... for example: -->
<TextBlock Text={Binding Path=InterestingThing}"/>
<!-- the divider -->
<Line X1="0" X2="200" Y1="0" Y2="0"
VerticalAlignment="Bottom"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>

Silverlight/WP7: I want to place an Button after the Listbox element which are data bound

I am fairly new to silverlight. I am developing on the windows phone platform.
I want to place a button at the end of the listbox entries which will be bound to data from the webservice (I am using a listbox template)
List item 1
List item 2
List item 3
List item 4
List item 5
List item 6
List item 7
List item 8
..Button..
I tried number of things of using grid/stackpanel etc to host the button and all my solutions place the button at the bottom of my screen instead of bottom of all the listbox entries which might span multiple screens.
XAML file I have is below. I want to add a button below the "LBoxItems"
<Grid x:Name="LayoutRoot"
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="ads" >
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Margin="24,24,0,12"
x:Name="SearchTitle">
<StackPanel Orientation="Horizontal">
<TextBlock FontWeight="Bold"
FontSize="{StaticResource PhoneFontSizeLarge}"
Text="{Binding Location}" />
<TextBlock FontSize="{StaticResource PhoneFontSizeLarge}"
Text=" > " />
<TextBlock FontWeight="Bold"
FontSize="{StaticResource PhoneFontSizeLarge}"
Text="{Binding Category}" />
</StackPanel>
<TextBlock FontSize="{StaticResource PhoneFontSizeMedium}"
Text="{Binding Converter={StaticResource SearchHistoryItemSubTitleConverter}}" />
</StackPanel>
</Grid>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentGrid"
Grid.Row="2">
<ListBox x:Name="LBoxItems"
HorizontalAlignment="Left"
Margin="24, 0"
SelectionChanged="LBoxItems_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="{StaticResource PhoneTouchTargetOverhang}" >
<TextBlock FontSize="{StaticResource PhoneFontSizeMediumLarge}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Foreground="{StaticResource PhoneAccentBrush}"
Text="{Binding Title.Text}" TextWrapping="Wrap" Margin="-4,20,0,0">
</TextBlock>
<TextBlock Text="{Binding PublishDate, Converter={StaticResource ItemPublishDateConverter}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
<l:SpinnerControl x:Name="SpinnerControl"
Width="55"
Height="55"
Grid.RowSpan="2" />
<TextBlock x:Name="TxtNoResultsMessage"
FontSize="{StaticResource PhoneFontSizeLarge}"
Text="No results found"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Grid.RowSpan="2"
Visibility="Collapsed" />
</Grid>
You could use a ScrollViewer:
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="800"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ListBox Grid.Row="0">
</ListBox>
<Button Grid.Row="1" Height="30" Content="Test"></Button>
</Grid>
</ScrollViewer>
Simply divide the Grid inside into two rows, the second one being for the Button.
For your specific case it would be:
<Grid x:Name="ContentGrid"
Grid.Row="2">
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="600"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ListBox x:Name="LBoxItems"
HorizontalAlignment="Left"
Margin="24, 0"
SelectionChanged="LBoxItems_SelectionChanged" Grid.Row="0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="{StaticResource PhoneTouchTargetOverhang}" >
<TextBlock FontSize="{StaticResource PhoneFontSizeMediumLarge}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Foreground="{StaticResource PhoneAccentBrush}"
Text="{Binding Title.Text}" TextWrapping="Wrap" Margin="-4,20,0,0">
</TextBlock>
<TextBlock Text="{Binding PublishDate, Converter={StaticResource ItemPublishDateConverter}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Sample" Height="30" Grid.Row="1" />
</Grid>
</ScrollViewer>
</Grid>
Of course, you can set the appropriate height depending on your situation.
What you want to do, really is to mix and match different items in the DataTemplate. If you're not really happy with how the other solutions work out I might consider adding a button to the datatemplate, but set its visibility to collapsed. Then for the very last entry, set its visibility to visible.
Either way you are in for a bit of a hack, but this way the button is in your list box. If all the button events point to the same handler, and only one is visible, you should be good to go.
I had the same problem and tried using the ScrollViewer approach, however I couldn't get rid of the 'stuck scrolling' issue until I disabled the vertical scrollbar on the listbox. Maybe this will help others too.

Resources