I need to capture the event when user click on empty jumplists, but I've tried the tap event , or put the datatemplate of jumplist in a button and tried click event, but neither of them worked. It's seem like I can't interact with empty section. The Longlistselector only provides 2 method : JumplistOpening and JumplistClosed. So how can I click on the gray jumplist ?
<phone:LongListSelector x:Name="llsMainSong"
IsGroupingEnabled="True" HideEmptyGroups="True"
JumpListStyle="{StaticResource JumpListStyle}"
GroupHeaderTemplate="{StaticResource GroupHeaderTemplate}"
ItemsSource="{Binding GroupedMainSongList}">
.........
</phone:LongListSelector>
<Style x:Key="JumpListStyle" TargetType="phone:LongListSelector">
<Setter Property="GridCellSize" Value="230,113"/>
<Setter Property="LayoutMode" Value="Grid" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Button Background="LightGray" Height="113" Margin="6" Click="Button_Click">
<TextBlock Text="{Binding Title}" FontSize="28" Padding="6" VerticalAlignment="Center"
Style="{StaticResource HelveBoldWhite}"/>
</Button>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
private void Button_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("click");
// ^ only jumplist which bind to group has data fired the event.
}
Related
I have a ComboBoxItem with a child button and I would like to prevent the ComboBox from dropping up (collapsing) when that button is clicked. Apparently it seems that the button is bubbling up the click event to the ComboBoxItem, causing the drop down to collapse.
<ComboBox DropDownOpened="OnWindowsDropDownOpened">
<ComboBox.ItemTemplateSelector>
<s:ComboBoxItemTemplateSelector>
<s:ComboBoxItemTemplateSelector.SelectedTemplate>
<DataTemplate>
<TextBlock Text="{Binding Description}" />
</DataTemplate>
</s:ComboBoxItemTemplateSelector.SelectedTemplate>
<s:ComboBoxItemTemplateSelector.DropDownTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<Button Command="{Binding DataContext.HighlightWindow, ElementName=Windows}" CommandParameter="{Binding}" MouseDown="Button_MouseDown" Click="Button_Click">
<md:PackIcon Kind="Target" />
</Button>
<TextBlock Text="{Binding Description}" />
</StackPanel>
</DataTemplate>
</s:ComboBoxItemTemplateSelector.DropDownTemplate>
</s:ComboBoxItemTemplateSelector>
</ComboBox.ItemTemplateSelector>
<ComboBox.ItemContainerStyle>
<Style BasedOn="{StaticResource MaterialDesignComboBoxItemStyle}" TargetType="ComboBoxItem">
<Setter Property="IsEnabled" Value="{Binding Valid}" />
<Setter Property="ToolTip">
<Setter.Value>
<TextBlock Text="{Binding Title}" />
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
As we can see, I tried both MouseDown and Click, handling the event, as follows:
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
e.Handled = true;
}
private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}
How do I do that? Also, is it possible to use MVVM code only (XAML-based code, no C#)?
Here's a screenshot of the ComboBox open
One you have not tested yet PreviewMouseLeftButtonDown and do it by the ComboBox. Or you can take another Preview* event.
private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = sender is Button;
}
<ComboBox DropDownOpened="OnWindowsDropDownOpened" PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown">
In WPF, elements are selected based on their behavior, not their visual appearance.
The behavior of the ComboBox (including) is to collapse when an item is selected.
If you do not need this, but need an explicit, separate action from the user to collapse the list, then use another element or a combination of them.
In my opinion, the Expander with a nested ListBox will be the most convenient for your task.
I have three buttons inside ListView.
I tried to click each of the button, however the ItemClick function was not triggered.
There is the xaml file of the ListView
<UserControl.Resources>
<DataTemplate x:Name="DefaultWideSideItemTemplate" x:DataType="ui:AppMenuItem">
<Grid>
<ui:ButtonWithIcon IconContent="{x:Bind Icon}"
Content="{x:Bind Name}"
Style="{StaticResource TransparentFontButtonStyle}"
/>
</Grid>
</DataTemplate>
<others:SideMenuItemTemplateSelector DefaultTemplate="{StaticResource DefaultWideSideItemTemplate}" x:Key="WideSideItemTemplateSelector"/>
</UserControl.Resources>
<ListView Style="{StaticResource HorizontalCenterListView}"
IsItemClickEnabled="True"
ItemsSource="{x:Bind MenuItemCollection}"
VerticalAlignment="Top"
x:Name="SideMenuListView"
Loaded="SideMenuListView_Loaded"
ItemClick="SideMenuListView_ItemClick"
ItemTemplateSelector="{StaticResource WideSideItemTemplateSelector}">
</ListView>
There is the code where ItemClick was defined.
public event EventHandler<AppMenuItem> SideMenuItemClick;
private void SideMenuListView_ItemClick(object sender, ItemClickEventArgs e)
{
// DO SOMETHING HERE
}
There is the xaml file of the ui:ButtonWithIcon
<Style x:Key="TransparentFontButtonStyle" TargetType="ui:ButtonWithIcon">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontSize" Value="30"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0,32,0,7"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ui:ButtonWithIcon">
<StackPanel>
<TextBlock
x:Name="IconContent"
Text="{Binding IconContent, RelativeSource={RelativeSource TemplatedParent}}"
HorizontalAlignment="Center"
FontFamily="{StaticResource SymbolThemeFontFamily}"
FontSize="30"/>
<TextBlock
x:Name="Text"
Text="{TemplateBinding Content}"
HorizontalAlignment="Center"
FontSize="14"
Margin="0,10,0,0"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
What did I understand wrong about ListView? Buttons can not be used in ListView?
Update: ButtonWithIcon
public class ButtonWithIcon : Button
{
public static readonly DependencyProperty IconContentProperty =
DependencyProperty.Register("IconContent", typeof(string), typeof(ButtonWithIcon), new PropertyMetadata(default));
public string IconContent
{
get { return (string)GetValue(IconContentProperty); }
set { SetValue(IconContentProperty, value); }
}
}
Update 2:
<DataTemplate x:Name="DefaultWideSideItemTemplate" x:DataType="ui:AppMenuItem">
<Grid>
<StackPanel Margin="0,32,0,7">
<TextBlock Text="{x:Bind Icon}"
HorizontalAlignment="Center"
FontFamily="{StaticResource SymbolThemeFontFamily}"
FontSize="30"/>
<TextBlock
Text="{x:Bind Name}"
HorizontalAlignment="Center"
Margin="0,10,0,0"
FontSize="14"/>
</StackPanel>
</Grid>
</DataTemplate>
If the ui:ButtonWithIcon is a custom button control, then this is expected behavior. When you click on the custom button, the click event is captured by the button, so the ListView won't trigger the ItemClick event. A simple way to confirm is that you could click on the place that does not belong to the custom button. It should fire the ItemClick event of the ListView.
Update:
Since your code is too messy, I made a simple test using some of your code:
<ListView HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
IsItemClickEnabled="True"
ItemsSource="{x:Bind MenuItemCollection}"
x:Name="SideMenuListView"
Loaded="SideMenuListView_Loaded"
ItemClick="SideMenuListView_ItemClick"
>
<ListView.ItemTemplate>
<DataTemplate >
<Grid>
<StackPanel Margin="0,32,0,7">
<TextBlock
Text="{Binding}"
HorizontalAlignment="Center"
Margin="0,10,0,0"
FontSize="14"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This works correctly.
You could remove the extra parts of your code to narrow down the issue. Start with a easy sample like the above.
So, I am designing a Universal Windows app which uses a ListView with data bound to it which i create programatically. The XAML for my page:
<ListView x:Name="lvEpisodeListSource" Margin="10,170,10,10" ItemsSource="{Binding Source={StaticResource EpisodeListSource}}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Episode">
<ListViewItem Background="CadetBlue" IsDoubleTapEnabled="False" IsHoldingEnabled="False" Tapped="ListViewItem_Tapped" IsRightTapEnabled="False" HorizontalAlignment="Stretch">
<TextBlock Name="AlbumBlock" Foreground="Black" FontWeight="Normal" FontSize="15" Margin="5,0,0,0"
Text="{x:Bind Name}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</ListViewItem>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
The data binds correctly and that all works fine. I am trying to then save the most recently clicked ListViewItem to LocalApplicationData. Currently, I am trying to do this by setting the Local App Data in the tapped event for the Items.
private void ListViewItem_Tapped(object sender, TappedRoutedEventArgs e)
{
myData data = ((ListViewItem)sender).DataContext as myData;
var clickedNumber = lvDataListSource.Items.IndexOf(((ListViewItem)sender));
}
This is currently not working and the clickedNumber always returns -1 no matter which I click. Is there a way to get the index of the item which called the tapped event or is there a better way to do want I want to accomplish?
Thanks!
Getting index or data corresponding to whole ListView (Parent Context) Instead of ListViewItem (Child Context) is always better.
Change your XAML to below.
<ListView x:Name="lvEpisodeListSource" Margin="10,170,10,10" ItemsSource="{Binding Source={StaticResource EpisodeListSource}}" SelectionChanged="ListView_SelectionChanged>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Episode">
<TextBlock Name="AlbumBlock" Foreground="Black" FontWeight="Normal" FontSize="15" Margin="5,0,0,0"
Text="{x:Bind Name}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
and your Selection Changed event would be
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListView view = (ListView)sender;
//Get Index of Selected Item
var index = view.SelectedIndex;
//Get Selected Item
var selectedItem = view.SelectedItem;
}
I would suggest always to refer parent resource and try to drill down to child unless you have a child click event which gives direct resource to get the parent.
I have this xaml. And I need to uncheck all other checkboxes where one is checked. I other words to allow to check only one. I add TreeViewItems on a runtime.
<TreeView Name="treeView_max" >
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<CheckBox Name="chk" Margin="2" Tag="{Binding}" Checked="checkBox_Checked">
</CheckBox>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.Resources>
</TreeView>
Adding TreeViewItems at runtime:
foreach (Genesyslab.Desktop.Modules.Core.Model.BusinessAttributes.IDispositionCodeValue item in listOfDispositionCodeValueItemsControl.Items)
{
TreeViewItem newChild2 = new TreeViewItem();
newChild2.Header = item.DisplayName.Remove(0,item.DisplayName.IndexOf("-") + 1);
treeView_max.Items.Add(newChild2);..........`
and
private void checkBox_Checked(object sender, RoutedEventArgs e)
{
try
{
//uncheck all checkboxes except selected one
}
catch (Exception es)
{
MessageBox.Show(es.ToString());
}
}
You can use RadioButton controls that belong to the same group instead, which will get you the behavior of only one option being able to be selected at a time.
Then edit the control template to display CheckBox controls in place of those RadioButton's, and bind the IsChecked property of each CheckBox to its parent RadioButton. Now when you "check" a CheckBox, all other CheckBox controls will become unchecked.
<TreeView Name="treeView_max" >
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<RadioButton Name="chk" Margin="2" Tag="{Binding}" GroupName="SomeGroup">
<RadioButton.Template>
<ControlTemplate>
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=RadioButton}}" />
</ControlTemplate>
</RadioButton.Template>
</RadioButton>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.Resources>
</TreeView>
Be careful about where you use this. Users are used to seeing RadioButton's when they're only able to select one option, and CheckBox's where they can select multiple options.
I have a ListBox with a DataTemplate. The template has a Button on it. Each item in the list shows the entity.
<ListBox Grid.Column="0"
x:Name="ThemesList"
ItemsSource="{Binding Themes}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
SelectedItem="{Binding SelectedTheme}"
ItemTemplate="{StaticResource ThemeListTemplate}"/>
<DataTemplate x:Key="ThemeListTemplate">
<Grid Grid.Column="1"
Grid.Row="0"
HorizontalAlignment="Right"
Margin="10">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Grid.Row="0"
HorizontalAlignment="Left"
Style="{StaticResource ElementButton}"
Command="{Binding Path=DataContext.ThemeEditorViewModel.OpenThemeEditorCommand, ElementName=ThemesBacklog}"
CommandParameter="{Binding Path=SelectedItem, ElementName=ThemesList}">
<TextBlock Text="Edit"/>
</Button>
<Button Grid.Row="1"
HorizontalAlignment="Left"
Style="{StaticResource ElementButton}"
Command="{Binding Path=DataContext.ThemeDeleteCommand, ElementName=ThemesBacklog}"
CommandParameter="{Binding Path=SelectedItem, ElementName=ThemesList}">
<TextBlock Text="Delete"/>
</Button>
</Grid>
</DataTemplate>
When you click on Button in the command is passed the property value SelectedItem. When you click on ListItem and then click Button - all fine. When I at once click on the Button - in the command is passed null. That is ListItem does not receive focus when you press the button located on this ListItem. How to solve this problem?
You could examine the IsKeyboardFocusWithin property on the ListBoxItems in a trigger, to find out whether a child (like your button), has focus, and set IsSelected to true if that is the case.
You do this by setting the ItemContainerStyle like this:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>