I created a simple usercontrol , a listbox and a button , when you click on the button opens a flyout with within a listview ,
my problem is that the ItemClick on item of listview does not work, does not access the method.
this is my code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"></TextBox>
<Button Grid.Column="1">
<Button.Flyout>
<Flyout>
<ListView ItemsSource="{x:Bind font}" ItemClick="ListView_ItemClick"></ListView>
</Flyout>
</Button.Flyout>
</Button>
</Grid>
I inserted a breakpoint in the method but in the execution does not access the method .
Thank you.
Yes it is just another property you have to activate in the ListView to make the ItemClick event work IsItemClickEnabled="True" :
<Button Grid.Column="1">
<Button.Flyout>
<Flyout>
<ListView IsItemClickEnabled="True" ItemClick="ListView_ItemClick">
<ListView.Items>
<ListViewItem>
<TextBlock Text="Hello"/>
</ListViewItem>
<ListViewItem>
<TextBlock Text="Hello"/>
</ListViewItem>
</ListView.Items>
</ListView>
</Flyout>
</Button.Flyout>
</Button>
SelectionChanged event of ListvIew can also be subscribed for achieving the result.
Related
In my UWP app which uses MVVMLight, I have a button contained in my ListViewItem and when clicked I want to display a flyout and provide additional actions for the specific ListViewItem but whenever I tap on the button, I get an error i.e.
System.InvalidCastException: Unable to cast object of
type 'Windows.UI.Xaml.Input.TappedRoutedEventArgs' to
type 'MyApp.ViewModels.ItemViewModel'.
at GalaSoft.MvvmLight.Command.RelayCommand`1.Execute(Object parameter)
at Microsoft.Xaml.Interactions.Core.InvokeCommandAction.Execute(Object
sender, Object parameter) at
Microsoft.Xaml.Interactivity.Interaction.ExecuteActions(Object sender,
ActionCollection actions, Object parameter)
at Microsoft.Xaml.Interactions.Core.EventTr
I understand to some extend why it's happening but how I can I fix this? The button contained in my ListViewItem data template is obviously being passed to the parent which is the listview and the DataTrigger that's defined in the Listview is capturing it.
All I want to do is display a flyout when this button is clicked to provide additional options.
<ListView.ItemTemplate>
<DataTemplate>
<Grid Background="{StaticResource SystemControlBackgroundAccentBrush5}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border Grid.Row="0"
Grid.Column="0"
Grid.RowSpan="4"
Width="90"
Height="90"
VerticalAlignment="Center"
Margin="5,5,0,5">
<Image Width="90"
Height="90"
Source="{Binding Logo}" />
</Border>
<Grid Grid.Row="0" Grid.Column="1" Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal"
Grid.Row="1" VerticalAlignment="Bottom">
<TextBlock Text="Id:" FontWeight="SemiBold" Foreground="White" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Subject}" Margin="10,0,0,0" Foreground="White" VerticalAlignment="Center"/>
</StackPanel>
<Button Width="30" Height="30"
Command="{Binding AdditionalInfoCommand}"
Grid.RowSpan="4"
Grid.Column="1"
Margin="0,0,12,0">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Stroke="{ThemeResource SystemControlBackgroundAccentBrush}"
Fill="{ThemeResource SystemControlBackgroundAccentBrush}"
StrokeThickness="2">
</Ellipse>
<Image Source="ms-appx:///Assets/Information.png" Width="30" Height="30" />
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
and my ListView has the following code:
<ListView ItemsSource="{Binding MyList}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
SelectionMode="Single">
<ListView.ItemTemplate>
.... as defined above
</ListView.ItemTemplate>
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Tapped">
<core:InvokeCommandAction Command="{Binding ItemClickCommand}"
CommandParameter="{Binding SelectedItem}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</ListView>
Any ideas on how I can resolve this?
UPDATE 1:
I'll re-phrase my question slightly. I've managed to bind the button displayed on the ListViewItem to a specific click event by introducing a RelayCommand (AdditionalInfoCommand) in the item's ViewModel. So now my main problem is the actual error mentioned above which is triggered after AdditionalInfoCommand and I assume it's because it is being captured by the ItemClickCommand. Strange as you would assume that it is using the same ViewModel.
Is there a way to no trigger the itemclick when this button is tapped?
Thanks.
Thierry
I figured it out.
When I tap the button inside my ListView DataTemplate, the button is being passed the Item's ViewModel which is correct but then the tap event is bubbled up back to the parent which is captured by:
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Tapped">
<core:InvokeCommandAction Command="{Binding ItemClickCommand}"
CommandParameter="{Binding SelectedItem}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
While there may be a solution to stop the event bubbling, to circumvent the problem, I changed my ItemClickCommand.
It was defined as follows:
private RelayCommand<MyItemViewModel> _itemClickCommand;
public RelayCommand<MyItemViewModel> ItemClickCommand
{
get { return this._itemClickCommand ?? (this._itemClickCommand =
new RelayCommand<MyItemViewModel>((viewModel) =>
ItemClickCommandAction(viewModel))); }
}
I simply changed it to:
private RelayCommand<object> _itemClickCommand;
public RelayCommand<object> ItemClickCommand
{
get { return this._itemClickCommand ?? (this._itemClickCommand =
new RelayCommand<object>((viewModel) =>
ItemClickCommandAction(viewModel))); }
}
I then changed the ItemClickCommandAction to take in an object instead of MyItemViewModel and now, within the method, I check the type of the ViewModel being passed:
private void ItemClickCommandAction(object currentObject)
{
if (currentObject is MyItemViewModel)
{
//go to next page
}
}
I have WinRT application with following GridView:
<GridView x:Name="RouteGrid"
ItemsSource="{Binding Routes}"
SelectedItem="{Binding SelectedRoute,
UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay}"
SelectionMode="Single">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Width="300" Margin="4">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock FontWeight="Bold" Text="{Binding TermText}" />
<TextBlock Grid.Column="1" Text="{Binding ConnectionObjects.Count}" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
I want to show a button instead of the second textblock when ever the item is selected because I want to allow my users to navigate to another view when they've selected.
I would like to do it in pure XAML because that is for me the cleanest way but I have no idea how to bind to the IsSelected property of the GridViewItem.
In WPF I would bind the Visibility property of the TextBlock and the button with a BooleanToVisibilityConverter and RelativeSource to the AncestorType GridViewItem and its property but that's not working because WinRT does not know AncestorType :(
Thanks for help.
I am building a Custom Control for Windows Phone 8.1. But the stackpanel is not scrolling down. StackPanel contains one ListView which shouws a TextBlock & another StackPanel which houses a Toggle Button.
<StackPanel Orientation="Vertical" >
<ListView Grid.Row="0" Background="RoyalBlue">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="Some Text" Foreground="Black" FontSize="20" TextAlignment="Center" ></TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackPanel Grid.Row="2" HorizontalAlignment="Stretch" Background="Red" Orientation="Horizontal">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ToggleButton Grid.Column="0" Content="Toggle Me" />
</Grid>
</StackPanel>
</StackPanel>
Stackpanel doesn't provide any scrolling.
You can wrap it into a ScrollViewer.
Also: listView already provides Scrolling.
But: The ListView inside stackpanel will pick up all your manipulation events. Also, a ListView inside a Stackpanel will have infinite heigt and therefore loose it's virtualization capabilities.
If you just want to have content above and/below the ListView, maybe use its Header/Footer properties.
Add ScrollViewer over the StackPanel and it will make it scrollable.
For Example:
<ScrollViewer Margin="12">
<StackPanel>
<TextBlock Text="content1" FontSize="48" />
<TextBlock Text="content1" FontSize="48" />
</StackPanel>
</ScrollViewer>
I have a dock panel to the left of my screen which contains a listbox. The listbox is populated with custom items, defined in another class. To the right of my listbox i have a gridsplitter.
When i click and drag my gridsplitter, the listbox gets resized as expected, howvever the items inside do not.
I would like the items inside to resize accordingly so i can use textrimming when the control would be cut off.
I currently have:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" MaxWidth="500" MinWidth="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<toolkit:DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,9,0">
<Button toolkit:DockPanel.Dock="Top" Height="30" Content="Create" Visibility="{Binding Path=IsVisible, Mode=TwoWay}" Command="{Binding Path=Create, Mode=TwoWay}" />
<ScrollViewer HorizontalAlignment="Stretch" VerticalAlignment="Stretch" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden">
<ListBox HorizontalAlignment="Stretch" ItemContainerStyle="{StaticResource ItemContainerStyle}" ItemsSource="{Binding Path=ViewModel, Mode=TwoWay}" SelectedItem="{Binding Path=Selected, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch">
<ContentControl HorizontalAlignment="Stretch">
<myNamespace:MycustomControl HorizontalAlignment="Stretch" DataContext="{Binding}" Height="40"/>
</ContentControl>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</toolkit:DockPanel>
<sdk:GridSplitter Width="10" HorizontalAlignment="Right" Grid.Row="1" Style="{StaticResource VerticalGridSplitterStyle}" />
Also within my custom item class, everything is defined HorizontalAlignment = Stretch and has no fixed width set.
Edit: Also i have tried binding my custom item's width to my listbox width with no luck.
It turned out that the horizontal scroll bar was causing the issue (even though it wasn't visible)
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Solved my issue
I have a Windows Phone 8 app using XAML/C#. My app has an ItemsControl that relies on a data template. My DataTemplate looks like the following:
<DataTemplate x:Key="myTemplate">
<Grid Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding DisplayName}" TextWrapping="NoWrap" Style="{StaticResource PhoneTextLargeStyle}" TextTrimming="WordEllipsis" >
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem x:Name="customerMenuItem" Foreground="White" Header="View Customer Profile" Click="customerMenuItem_Click" Tag="{Binding Path=CustomerName}" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</TextBlock>
<TextBlock Text="{Binding Summary}" TextWrapping="NoWrap" Grid.Row="1" Style="{StaticResource PhoneTextSmallStyle}" />
</Grid>
<StackPanel Orientation="Horizontal" Grid.Column="1"><!-- Stuff here --></StackPanel>
</Grid>
</DataTemplate>
This DataTemplate is referenced in the main part of my XAML as shown here:
<Grid x:Name="ContentPanel" Grid.Row="1" Grid.ColumnSpan="2" Margin="12,0,12,0">
<ScrollViewer>
<ItemsControl x:Name="myItemsControl" ItemTemplate="{StaticResource myTemplate}" ItemsSource="{Binding Customers}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</Grid>
Please note, the "toolkit" namespace comes from clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit. When I hold my finger (or mouse) on the TextBlock, a context menu appears. However, I never see the words "View Customer Profile". I just see a block box that represents the context menu itself. I know that the item is there though. I know because the customerMenuItem_Click event successfully fires. I have a MessageBox in there that shows the value of the Tag. That value is always correct. For some reason though the menu item text is not appearing. What am I doing wrong?
You put Foreground = "White". Context menu is on white background. That is why you don't see your menu item.