LongListSelector different areas to click - xaml

I use LongListSelector to render my db items, Item_SelectionChanged - is default procedure when I click any item. I need to place extra button on LongListSelector item, with different "click" method. But doing this way every time I execute OtherClickOption code it also triggers Item_SelectionChanged as well. Is it possible to prevent this event?
<phone:LongListSelector
x:Name="ItemsLongListSelector"
SelectionChanged="Item_SelectionChanged">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="73"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding ItemText}"/>
<Button Grid.Column="1" Click="OtherClickOption" />
......

First, remove the SelectionChanged event from the LongListSelector. Then add something like a transparent grid to your DataTemplate covering the UI other than the Button and add a Tapped event handler to it where you execute the code you used to execute in the SelectionChanged event handler (modified of course).

Related

UWP - GridView : how to add an "Add" button after the last item?

I use a GridView to display photos and I search an elegant way to allow user to add a new item to a form.
The form contains a lot of fields: it is displayed in a Pivot, where each PivotItem represents a category of the form.
Some categories contain one or more child items: they are displayed through a Master-Detail page.
It's in this page that I need to display a list of photos: as a photo represents a "sub sub item" of the form, I wouldn't manage the add of a new photo through the CommandBar. But I would like to use an "Add" button after the last item of the GridView containing the photos.
At this time I only found a solution that partially work:
Here is the XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Photos" Grid.Row="0"/>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<GridView ItemsSource="{Binding images}">
<GridView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="1"
Padding="10"
Height="150" Width="190">
<Image Stretch="UniformToFill"
Source="{Binding bitmap_image}" />
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<Border BorderBrush="Gray" BorderThickness="1"
Padding="10"
Height="150" Width="190">
<Button Command="{Binding Path=DataContext.AddPhotoCommand, ElementName=DetailsPage}"
Height="100" Width="100">
<Viewbox>
<SymbolIcon Symbol="Add"/>
</Viewbox>
</Button>
</Border>
</StackPanel>
</Grid>
As I use a StackPanel, the Add button is no longer visible if I display 3 photos...
=> Is there a better way to do this? Or do you see a an alternative? I'm looking for doing this through a DataTemplateSelector, but that would require me to create a "false" object for displaying the add button...
As I use a StackPanel, the Add button is no longer visible if I display 3 photos...
If you don't mind the button is in the next line of your last photo, you can use WinRTXamlToolkit's WrapPanel instead of StackPanel to avoid the pictures goes out of the window and put the button inside the GridView's FooterTemplate:
Xaml:
<Page
x:Class="AddButtonSample.MainPage"
xmlns:controls="using:WinRTXamlToolkit.Controls"
...
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Photos" Grid.Row="0"/>
<controls:WrapPanel Orientation="Horizontal" Grid.Row="1">
<GridView ItemsSource="{Binding images}">
<GridView.FooterTemplate>
<DataTemplate>
<Button Command="{Binding Path=AddPhotoCommand}" Height="100" Width="100">
<Viewbox>
<SymbolIcon Symbol="Add"/>
</Viewbox>
</Button>
</DataTemplate>
</GridView.FooterTemplate>
<GridView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="1"
Padding="10"
Height="150" Width="190">
<Image Stretch="UniformToFill"
Source="{Binding bitmap_image}" />
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</controls:WrapPanel>
</Grid>
Result:
If you really want to put the Button side by side after the last item of GridView. The only Option is DataTemplateSelector.
The best solution might be to use a CommandBar and put the "Add" button in the very bottom of the panel, as that would be most consistent with UWP design guidelines. GridView also has a FooterTemplate, which allows you to add some XAML in the footer of the whole GridView (but not directly after the items).
If you still want to have the add item as part of the GridView contents, you will really need to use the fake item and a DataTemplateSelector. This solution is not very clean, but probably is the only simple way.
I tried to do something similar for my own app too, but there really isn't an obvious way to achieve it. A little background on what my app does: it's a flashcard app that displays decks of card in a gridview on the homepage, with an add button being at the front of the gridview. This is what I did:
for my deck class, I gave it a bool attribute isButton
in the observablecollection of decks, set the first item's isButton to true
make two datatemplates for the gridview (deck and button) and make a data template picker for the gridview, and check the isButton attribute
if isButton is true, the template picker will use the button template
otherwise use deck template

Transparent Grid in Windows Phone?

I'm trying to write a page for WP8 which plays video, using the MediaElement API.
I am having difficulties in placing the play/pause controls over the video.
I am currently using a grid to house the controls over the video. The problem is that I cannot make the grid transparent. This is the XAML -
<StackPanel Background="Transparent">
<MediaElement Name="media" Source="http://video-js.zencoder.com/oceans-clip.mp4" AutoPlay="True"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<!-- Play button. -->
<!-- Pause button. -->
<Grid Background="Transparent" VerticalAlignment="Bottom" Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="85" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Source="Assets\transport.pause.png" Height="79" Width="79"/>
<Image Grid.Column="1" Source="Assets\transport.play.png" Height="79" Width="79"/>
</Grid>
</StackPanel>
I can still see a black portion where the Grid is.
Is there a better way to accomplish this?
You've put the controls in a StackPanel. That means that you'll end up with:
StackPanel
MediaElement
Grid
Button/Image
Button/Image
A StackPanel is designed to stack controls either horizontally or vertically. It is not for overlaying controls. So, the black background you're seeing is the background beneath the Grid, which is likely the default background brush/color of the application (black).
If you instead were to use a Grid to host the controls, you can use an overlay as you need to:
<Grid x:Name="ContentPanel" >
<Grid>
<MediaElement Name="media" Source="Assets/sample_mpeg4.mp4"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Grid Background="#80000000" VerticalAlignment="Center" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" >Pause</Button>
<Button Grid.Column="1" Click="Button_Click_1" >Play</Button>
</Grid>
</Grid>
</Grid>
It's now:
Grid
MediaElement
Grid
Button
Button
It would look something like this:
Using the Grid, I've put both the MediaElement and the inner Grid in the same cell (by using the default attached property values for Row and Column which are `0').
In the above code, I've used a Grid to layout the MediaElement and another Grid which will layout the two Buttons I've used. In this case, I've centered the Grid with the Buttons so that the buttons appear in the center of the MediaElement.
I've also used a somewhat transparent Background for the Grid which contains the buttons.
I've dealt with this issue before but can't remember exactly how I solved it. I remember researching this, which is using visual media as a Brush to then paint the background of the Grid that houses the buttons. IIRC, the issue is not necessarily with the Grid, it's with anything overlaying the MediaElement. Because of some special drawing procedure involved with the MediaElement it doesn't handle overlays and transparencies well. There is a solution, but like I said I can't completely remember. But try out using the video as a Brush for the background of the Grid.

How to remove "tap" event from “Group Header” and manually call the “Jump List” in “Long List Selector”?

I am using Long List Selector in my app, I have made groups and group headers in it.
Now, I am adding a button in the group header and want the button to open new page.
But, when I click on the button it navigates to new page as well as opens the "Jump List". I don't want the jump list when I click the button.
I have found this link, but, here is no clear answer.
Is there any way to disable the "tap" event on "group header" and call when needed?
My code is:
xaml:
<DataTemplate x:Key="groupHeaderTemplate">
<Border HorizontalAlignment="Stretch" Height="70" Background="{Binding Converter={StaticResource BackgroundConverter}}" Margin="6">
<Grid HorizontalAlignment="Stretch" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}"
FontSize="40" Padding="6"
VerticalAlignment="Center"
Foreground="{Binding Converter={StaticResource ForegroundConverter}}" />
<Button Content="addNew" Name="addNew_btn" Grid.Column="1" Click="addNew_btn_Click_1" Tag="{Binding transType}" />
</Grid>
</Border>
</DataTemplate>
CS:
private void addNew_btn_Click_1(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/Expense.xaml", UriKind.Relative));
}
If I understand right, you want to open the jump list when you tap outside the button and open another page when you tap on a button. To do that you can just register for the Tap event instead of click on the button and inside the Tap event handler set e.Handled = true; that will prevent the event to bubble and the the Jump list to open when pressing the button.

Repeat EntranceThemeTransition

I have a simple TabControl done using templated RadioButtons and Grids which change visibility when IsChecked on a RadioButton changes, something like this:
<Grid Name="TabGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<RadioButton x:Name="RadioButton1" Content="Latest" Style="{StaticResource TabRadioButtonStyle}" IsChecked="True" GroupName="G1"/>
<RadioButton x:Name="RadioButton2" Content="Popular" Style="{StaticResource TabRadioButtonStyle}" IsChecked="False" GroupName="G1" Margin="30,0,0,0" />
</StackPanel>
Now, every grid inside has EntranceThemeTransition defined, something like this:
<GridGrid.Row="1" Visibility="{Binding ElementName=RadioButton1, Path=IsChecked, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition />
</TransitionCollection>
</Grid.ChildrenTransitions>
As I understand, the EntranceThemeTransition displays only when the items are first shown. Is there a way to force EntranceThemeTransition to repeat every time the visibility of the Grid changes?
This doesn't exactly answer your questions but I think will help many people landing on here:
If you want to repeat the entrance animations for items in a databound listbox, I have found only one way of doing this:
Set the DataContext of the listbox to null (this removes the items).
Set the DataContext of the listbox back to your list/observable collection (this recreates the items and adds them to the listbox with an animation).
By reseting the DataContext you are creating new listbox items and they aren't marked as having entered the view yet.
In regards to your question; I think you'll need to create a new version of the grid to play the entrance animation again.

Deleting element from ItemsControl by pressing button XAML C++/CX

I am trying to delete an element from the following ItemsControl without using Window.CommandBinding. Is there an easier way to do this?
XAML:
<ItemsControl ItemsSource="{Binding Path=MyStringArray}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="Abcd"/>
<Button Content="-" Click="Button_Click_1"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
If there is not an easier way, how can it be done with Window.CommandBindings
Also, in this code, how can I make the width of the first button take the entire width of the screen minus the width of the second button?
The easiest way to remove an item in an itemscontrol using a button on the item template is using a command binding with the command parameter bound to the current item. You then remove the current item from the backing collection.
To achieve the button spacing you're looking for, use a grid for layout. Create two GridColumns. Give the first one a width of * and the second one a width of Auto. Assuming you have the spacing for your ItemsControl set correctly, this will achieve the spacing your looking for.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="Abcd"/>
<Button Grid.Column="1" Content="-" Command="{Binding YourCommand}" CommandParamter={Binding}/>
</Grid>
See here for a more complete commmand binding example and here for a convenience class for command binding.