How to get the item I was holding in the listview - xaml

I am working with listview control in win8. I want to add an event when I hold on the item, and delete the item.
the xaml and event code like this:
<ListView x:Name="ImageList" VerticalAlignment="Bottom" Background="LightGray" Width="1050" BorderBrush="Black" BorderThickness="2" Grid.Column="1"
Holding="ListView_Hold1" SelectionChanged="OnSelectedChanged" SelectionMode="Single" Height="152" ScrollViewer.HorizontalScrollBarVisibility="Auto" ItemContainerStyle="{StaticResource ListViewItemStyle1}" Style="{StaticResource ListViewStyle1}">
<ListView.ItemTemplate>
<DataTemplate>
<Image Opacity="0.7" Width="150" Height="125" Stretch="UniformToFill" Source="{Binding}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
private async void ListView_Hold1(object sender, Windows.UI.Xaml.Input.HoldingRoutedEventArgs e)
{...}
It seems that I can not get any information from holdingroutdEventArgs but the attribute of originalsource. But it is the image and no way access to iteml
I have found a relative question: "how to get the clicked item in the listview". it can be solved by getting the attribute of selecteditem.
anyone can help me ? give me some clue.

You should be able to get it from the HoldingRoutedEventArgs.OriginalSource.DataContext, in your case: (Assuming that the ListView.ItemSource is a list of ImageModel)
private async void ListView_Hold1(object sender, Windows.UI.Xaml.Input.HoldingRoutedEventArgs args)
{
var source = (FrameworkElement)args.OriginalSource;
var imageModel = (ImageModel)source.DataContext;
}

You can get the index of the item using the SelectedIndex property (but for these work you have to select, by pressing, and after hold the item)
int i = imageList.SelectedIndex;
So to delete the item you can use the RemoveAt() method
imageList.Items.RemoveAt(i);

Related

Is there a way to change the parent content for a popup in WinUI3?

In WinUI3 it seems that you are unable to modify the duration of a tooltip (similar to how WPF allowed a duration change with the ToolTipService.ShowDuration).
As such, I'm attempting to replicate the behavior using a Popup control such that the Popup will remain visible as long as the mouse is hovered over an element (utilizing the element's OnPointerEntered / OnPointerExited events to modify the IsOpen property of the Popup).
This displays the Popup correctly, however in my case the Popup exists inside a Grid which is inside the ListView.ItemTemplate for a ListView. ala:
<ListView>
<DataTemplate>
<Grid>
<TextBlock/>
<Popup/>
</Grid>
</DataTemplate>
</ListView>
Thus the popup only overlays the <Grid>, but still gets clipped within the region of the DataTemplate.
I'd like to have the popup overlay the <ListView> itself instead - is there a way to specify which content the popup will overlay such that it will overlay the <ListView>?
Or even better - to have it overlay all elements of the Window (replicating the placement of a tooltip?)
Is there a way to change the parent content for a popup in WinUI3?
Sure, you could place Popup at same level as ListView in current page. And listen ListView item PointerEntered and PointerExited event then pass current item datacontext to popup control.
Xaml
<ListView
Margin="0,10,0,45"
ItemsSource="{x:Bind Items}"
Visibility="Visible">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel
Orientation="Vertical"
PointerEntered="StackPanel_PointerEntered"
PointerExited="StackPanel_PointerExited">
<TextBlock x:Name="Id" Text="{Binding ID}" />
<TextBox
x:Name="FirstName"
GettingFocus="FirstName_GettingFocus"
Text="{Binding FirstName}" />
<TextBox x:Name="LastName" Text="{Binding LastName}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Popup
x:Name="PopupTip"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Popup.ChildTransitions>
<TransitionCollection>
<PaneThemeTransition Edge="Bottom" />
</TransitionCollection>
</Popup.ChildTransitions>
<StackPanel
Width="150"
Height="80"
Background="LightGray"
CornerRadius="4">
<TextBlock
x:Name="InfoLabel"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding ID}" />
</StackPanel>
</Popup>
Code behind
private void StackPanel_PointerEntered(object sender, PointerRoutedEventArgs e)
{
var ItemDataContext = (sender as FrameworkElement).DataContext;
PopupTip.DataContext = ItemDataContext;
PopupTip.IsOpen = true;
}
private void StackPanel_PointerExited(object sender, PointerRoutedEventArgs e)
{
PopupTip.DataContext = null;
PopupTip.IsOpen = false;
}

GridView ItemClick event not working?

I am working on a UWP application, trying to implement ItemClick event on a GridView, however, when I click on an Item, nothing happens.
The relevant code is below:
Book.xaml:
<Page.DataContext>
<vm:BookViewModel x:Name="ViewModel" />
</Page.DataContext>
<GridView Grid.Row="1"
Padding="18"
ItemsSource="{Binding Source={StaticResource BookViewSource}}"
IsItemClickEnabled="True"
ItemClick="{x:Bind ViewModel.BookGroups_OnItemClick}">
BookViewModel.cs:
public void NavigateToDetails(string url)
{
NavigationService.Navigate(typeof(Views.DetailPage), url);
}
public void BookGroups_OnItemClick(object sender, ItemClickEventArgs e)
{
var bookHeader = (BookGroup)e.ClickedItem;
NavigateToDetails(bookHeader.url);
}
I would really appreciate your help, thank you!
EDIT : Book.xaml GrdivView source:
<GridView Grid.Row="1"
Padding="18"
ItemsSource="{Binding Source={StaticResource BookViewSource}}"
IsItemClickEnabled="True"
ItemClick="{x:Bind ViewModel.BookGroups_OnItemClick}"
>
<GridView.ItemTemplate>
<DataTemplate>
<Grid Width="250" Height="250" >
<Border VerticalAlignment="Bottom" Background="#AA000000">
<TextBlock Text="{Binding name}" Margin="12" Foreground="White"/>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding name}" Margin="-12,0,0,0"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
I have copied your code 1:1 into a new project and the NavigateToDetails method does get called. Please try to put a breakpoint in the method to see if it gets hit. If it does, there might be a problem with the NavigationService. Otherwise, the problem is very likely in the GridView.ItemTemplate - it may be possible that there is a control that handles the click event so that it doesn't bubble up to the GridView at all.
So finally as I deleted the following part from Book.xaml, the item click works fine:
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding name}" Margin="-12,0,0,0"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</GridView.GroupStyle>
I did not find out what caused the problem, but now it works.
Thank you for your help and time :)

Check the checkbox = listviewitem row is selected

I am developing a UWP app.
I have a listview which the listviewitem has a checkbox and the content. What I need to implement is, when I check the checkbox, the related listviewitem is selected; when I uncheck it, the related listviewitem is deselected. My listview need support multi-selection.
Here is my xmal code:
<ListView Grid.Row="1" x:Name="SuggestListView" ItemsSource="{Binding SuggestList}" IsMultiSelectCheckBoxEnabled="True" IsItemClickEnabled="True" SelectionChanged="SuggestListView_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ctl:PersonUserControl HorizontalAlignment="Left"/>
<CheckBox Name="CheckBoxhhh" HorizontalAlignment="Right" IsChecked="{Binding IsSelected, Mode=TwoWay}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="SelectionChanged">
<Core:InvokeCommandAction Command="{Binding SelectSuggestPersonCommand}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ListView>
Can anybody throw me some lights?
You're on the right track but if you're wanting to use this with the IsMultiSelectCheckBoxEnabled set to true, you don't need to implement your own Checkbox in the ItemTemplate.
From what I gathered from your comments on the question, you're looking for a way to get the items from one collection to another when you're selecting from the other.
So remove the checkbox and also add the SelectionMode="Multiple" to your ListView.
In the Behavior of your ListView, you're listening for the SelectionChanged so remove this from your ListView and it should look like this:
<ListView Grid.Row="1" x:Name="SuggestListView" ItemsSource="{Binding SuggestList}" IsMultiSelectCheckBoxEnabled="True" SelectionMode="Multiple">
<ListView.ItemTemplate>
<DataTemplate>
<ctl:PersonUserControl HorizontalAlignment="Left"/>
</DataTemplate>
</ListView.ItemTemplate>
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="SelectionChanged">
<Core:InvokeCommandAction Command="{Binding SelectSuggestPersonCommand}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ListView>
Then in your bound Command for the SelectionChanged event you're utilising in the Behavior, you'll want to add the items that are added and removed to an ObservableCollection which you can bind to from your other ListView to show the selected ones.
The method will look something like this:
public ObservableCollection<ItemType> SelectedItems { get; private set; }
private void SelectedItemsChanged(SelectionChangedEventArgs args)
{
foreach (var item in args.AddedItems)
{
var vm = item as ItemType;
if (vm == null)
{
continue;
}
this.SelectedItems.Add(vm);
}
foreach (var item in args.RemovedItems)
{
var vm = item as ItemType;
if (vm == null)
{
continue;
}
this.SelectedItems.Remove(vm);
}
}

Reference a childitem of a grid defined by a datatemplate in windows 8

I am having a hard time doing the following:
I have a datatemplate which populates a gridview with grids. The number of grids to be generated depends on the data binding, that is how many of the data objects it returns. My grid, which is defined in the datatemplate, contains some controls; namely an image and a textbox.
I am trying to reference the image on the event selectionchanged of the gridview but I am failing majestically. Here is a sample code of what I am trying to do:
The datatemplate (in style.xaml):
<DataTemplate x:Key="tmplMenu">
<Grid Width="100"
Height="100"
Margin="0,0,10,10">
<Border Background="{Binding bgColor}" />
<Image Source="{Binding imgPath}"
Stretch="None"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
<TextBlock Text="{Binding description}"
HorizontalAlignment="Right"
VerticalAlignment="Bottom" />
</Grid>
</DataTemplate>
The gridview (in mainpage.xaml for example):
<GridView ItemTemplate="{StaticResource tmplMenu}"
x:Name="myGrid"
Margin="50,20,0,50"
Width="360"
SelectionChanged="myGrid_SelectionChanged">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal"></WrapGrid>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
Now the selectionChanged event on the gridview (where I would like to reference the image in the datatemplate):
private void myGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
/**REFERENCE IMAGE (which is a child item of the generated grid) OF CLICKED GRID (which is a child item of the gridview) HERE **/
}
Here, the selectionChangedEventArgs e returns the data object which is used to generate the grid instead of the grid itself.
Can anyone help me out in referencing the image control of the clicked item?

Silverlight 4 Overloaded Textbox's textchanged event is fired by parent textbox

I have an custom textbox that I got from http://blog.roboblob.com/2010/07/16/custom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding/comment-page-1/:
public class ImmediateTextBox : TextBox
{
public ImmediateTextBox()
{
this.Loaded += ImmediateTextBox_Loaded;
}
void ImmediateTextBox_Loaded(object sender, RoutedEventArgs e)
{
this.GotFocus += ImmediateTextBox_GotFocus;
this.TextChanged += new TextChangedEventHandler(ImmediateTextBox_TextChanged);
}
void ImmediateTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox txt = sender as TextBox;
if (txt != null)
{
BindingExpression bindExp = txt.GetBindingExpression(TextBox.TextProperty);
if (bindExp != null)
{
bindExp.UpdateSource();
}//if
}//if
}
void ImmediateTextBox_GotFocus(object sender, RoutedEventArgs e)
{
this.SelectAll();
}
}
In my xaml I am using this, and it works fine, except when I have it nested and the parent container has a ImmediateTextBox:
<ItemsControl Grid.Column="1" ItemsSource="{Binding Path=LstForecast}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<customControls:ImmediateTextBox Padding="8" Height="36" Text="{Binding Path=DForecastQuantityShippedTotal,
StringFormat=\{0:n0\},
Mode=TwoWay,
Converter={StaticResource StringToNullableDoubleConverter}}"
Width="70" IsEnabled="{Binding Path=IsForecastUserEditable}"/>
<!--Weeks-->
<ItemsControl ItemsSource="{Binding Path=LstWeeks}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<customControls:ImmediateTextBox Padding="8" Width="70" Height="36"
Text="{Binding Path=DForecastQuantityShippedTotal, StringFormat=\{0:n0\}, Mode=TwoWay, Converter={StaticResource StringToNullableDoubleConverter}}"
IsEnabled="{Binding Path=IsForecastUserEditable}"/>
<!--days data-->
<ItemsControl ItemsSource="{Binding Path=LstDays}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<customControls:ImmediateTextBox Padding="8" Width="70" Height="36"
Text="{Binding Path=DForecastAutoManual,
StringFormat=\{0:n0\},
Mode=TwoWay,
Converter={StaticResource StringToNullableDoubleConverter}}"
IsEnabled="{Binding Path=IsForecastUserEditable}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!--end days data-->
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!--end weeks-->
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
At the lowest level it gets really funky. modifying the previous and sometimes the following generated textboxes. If I use an autocompletebox, of course it works. The problem is that I am wanting to add behaviors to the textbox for copy/paste/selectall, etc that I can't do with the autocompletebox, since there is no selectedtext or a selectall() method. Also I noticed in the RoutedEventArgs, the originalsource is null. I figured using that would cause it to work, but no. Any help? thanks in advance.
Okay so I figured it out. I have each text-box bound to properties. When any one of these text-boxes are modified then the bound properties of the ViewModel update each other. When that happens they update the text-box where it occurs and not just the property, because it is a 2-way binding. So when there is an update that is caused by the user's input it updates. It shouldn't when the user doesn't type anything in that text-box (when the text-box is being updated from the algorithm.
My solution is creating a boolean property "isUser" in ImmediateTextBox. When my overridden OnKeyDown or OnMouseLeftButtonPressed are called I set isUser to true. When the text changes from the user typing in or pasting in something, then i update the binding and set isUser to false.