i want to select a listviewitem, where a button was clicked.
Here is my Listview with 2 llistviewitems
I click the X-Button and want to delete these item out of the list. How i get that item?
I have these code:
private void Delete_Click(object sender, RoutedEventArgs e)
{
var item = sender as ListViewItem;
var obj = item.Content as object;
List.Remove(obj);
}
Edit: The Binding of the ListView
<ListView x:Name="listview">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="Bild "/>
<TextBlock Text="{Binding Title}"/>
<Button x:Name="Change" Content="Change" Margin="250,0,0,0" Click="Change_Click"/>
<Button x:Name="Delete" Content="X" Margin="10,0,0,0" Click="Delete_Click"/>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Height" Value="50"/>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="lvSeriesItem_PreviewMouseLeftButtonDown"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
please use this instead.The control that raised the event is not the listbox but the button.The button as a datacontext of your collection model object. so this should workd
private void Delete_Click(object sender, RoutedEventArgs e)
{
var button= sender as Button;
var obj =(YourModelHere)button.DataContext;
List.Remove(obj);
}
sender will be the Button, your data item will be the DataContext of said button.
Related
<ListBox
x:Name="listBox"
SelectionChanged="listBox_SelectionChanged">
</ListBox>
void listBox_SelectionChanged(object sender, RoutedEventArgs e) {
// This method is only called when a selection is changed.
}
However, I need to call a function that executes even if the already selected item in the list box is clicked again (which would make it selected had it not already been).
I tried the Selected event handler but received this error in visual studio:
Error CS1061 'ListBox' does not contain a definition for 'Selected' and no accessible extension method 'Selected' accepting a first argument of type 'ListBox' could be found (are you missing a using directive or an assembly reference?)
Is there any other event I might be missing?
Thank you.
In .xaml (assume ListBox item is Grid)
<ListBox
x:Name="listBox"
SelectionChanged="listBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid PreviewMouseDown="listBox_OnPreviewMouseDown">
<!-- Content -->
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In .xaml.cs (assume MyListItemType is the type of the item in ListBox)
private void listBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var clickedItem = (sender as FrameworkElement)?.DataContext as MyListItemType;
if (clickedItem != listBox.SelectedItem) return;
// same item is selected
// ..
}
private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var clickedItem = (sender as FrameworkElement)?.DataContext as MyListItemType;
// new item is selected
// ..
}
First Example:
<UniformGrid>
<ListBox>
<ListBox.ItemsSource>
<sys:String>QWERTY</sys:String>
</ListBox.ItemsSource>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<EventSetter Event="PreviewMouseLeftButtonDown"
Handler="OnItemClick"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<TextBlock x:Name="tBlock"/>
</UniformGrid>
</Window>
private int count = 0;
private void OnItemClick(object sender, MouseButtonEventArgs e)
{
count++;
tBlock.Text += $"{count}: {((ListBoxItem)sender).Content}{Environment.NewLine}";
}
Second Example:
<ListBox SelectionChanged="OnSelection"
HorizontalContentAlignment="Stretch">
<ListBox.ItemsSource>
<sys:String>QWERTY</sys:String>
</ListBox.ItemsSource>
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type sys:Char}">
<Grid>
<TextBlock x:Name="PART_TBlock" Text="{Binding}"/>
<Button x:Name="PART_Btn" Content="{Binding}" Click="OnReselection"
BorderThickness="0" Background="Transparent"
HorizontalContentAlignment="Left"
Visibility="Collapsed"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"
Value="True">
<Setter TargetName="PART_TBlock" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="PART_Btn" Property="Visibility" Value="Visible"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock x:Name="tBlockReselection"/>
</UniformGrid>
</Window>
private void OnSelection(object sender, SelectionChangedEventArgs e)
{
tBlockReselection.Text += $"Selected: {((ListBox)sender).SelectedItem}{Environment.NewLine}";
}
private void OnReselection(object sender, RoutedEventArgs e)
{
tBlockReselection.Text += $"Reselected: {((Button)sender).Content}{Environment.NewLine}";
}
Third Example:
<ItemsControl HorizontalContentAlignment="Stretch">
<ItemsControl.ItemsSource>
<sys:String>QWERTY</sys:String>
</ItemsControl.ItemsSource>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type sys:Char}">
<Button Content="{Binding}" Click="OnClickselection"
HorizontalContentAlignment="Left"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock x:Name="tBlockClickSelection"/>
</UniformGrid>
</Window>
private void OnClickselection(object sender, RoutedEventArgs e)
{
tBlockClickSelection.Text += $"ClickSelection: {((Button)sender).Content}{Environment.NewLine}";
}
Is there any way to find out witch Item number is under the pointer on GridView? I like to show short information about the item under the mouse without selecting the item by any click.
You could handle the PointerEntered and PointerExited events for the root element in your ItemTemplate.
XAML:
<GridView>
<x:Int32>1</x:Int32>
<x:Int32>2</x:Int32>
<x:Int32>3</x:Int32>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemTemplate>
<DataTemplate>
<Grid PointerEntered="TextBlock_PointerEntered"
PointerExited="TextBlock_PointerExited"
Background="Transparent">
<TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<TextBlock x:Name="tb" />
Code:
private void TextBlock_PointerEntered(object sender, PointerRoutedEventArgs e)
{
Panel root = sender as Panel;
var dataObject = root.DataContext;
tb.Text = dataObject.ToString(); //displays the currently pointed number in "tb"
}
private void TextBlock_PointerExited(object sender, PointerRoutedEventArgs e)
{
tb.Text = string.Empty;
}
In Windows Universal app, I have a pivot table which every tab content have gridview, gridview items are multi select mode,
What I want that if any one item once checked (selected), then it unable to unselect(uncheck)
<Grid DataContext="{Binding Path=Value}">
<GridView x:Name="categoryItemsGV"
Margin="5,5,0,0"
SizeChanged="categoryItemsGV_SizeChanged"
IsItemClickEnabled="True"
ItemClick="categoryItemsGV_ItemClick"
SelectionMode="Single"
ItemsSource="{Binding}">
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<!--<Setter Property="VerticalContentAlignment" Value="Center"/>-->
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemTemplate>
<DataTemplate>
<Grid Width="195" Height="43" Margin="3">
<StackPanel Width="193" Height="40" Background="Gray" Opacity="0.5" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
<StackPanel Orientation="Horizontal" Width="193" Height="40" Padding="7,7,0,0" Background="#FDFCC2" HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBlock Text="{Binding ProductOptionLineName}" FontSize="18" MaxLines="1" TextTrimming="CharacterEllipsis" Visibility="{Binding Converter={StaticResource langToVisibilityConverter}, ConverterParameter='CH', Mode=OneWay}">
</TextBlock>
<TextBlock Text="{Binding ProductOptionLineNameEn}" FontSize="18" MaxLines="1" TextTrimming="CharacterEllipsis" Visibility="{Binding Converter={StaticResource langToVisibilityConverter}, ConverterParameter='EN', Mode=OneWay}"/>
<TextBlock Text="{Binding ExtraPriceString}" FontSize="18" Margin="2,0,0,0"></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
private async void categoryItemsGV_ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as ProductOptionLineModel;
}
We can use the SelectRange(ItemIndexRange) method to selects a block of items described by the ItemIndexRange.
When you call SelectRange(ItemIndexRange), all items in the specified range are selected, regardless of their original selection state. You can select all items in a collection by using an ItemIndexRange with a FirstIndex value of 0 and a Length value equal to the number of items in the collection.
For more info, see Remarks of the SelectRange(ItemIndexRange).
We can use the ItemClick to get which item is be clicked. Then we can add the SelectionChanged event and set the number of the clicked item to the SelectRange method.
For example:
private int number;
private void categoryItemsGV_ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as ProductOptionLineModel;
number = ProductOptionLineModels.IndexOf(item);
}
private void categoryItemsGV_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
categoryItemsGV.SelectRange(new ItemIndexRange(number, 1));
}
If we want to keep item selected as it was already selected, use below approach.
private async void categoryItemsGV_ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as ProductOptionLineModel;
GridView gv = sender as GridView;
gv.SelectedItems.Remove(item);
}
and if we want to keep item deselect on click (prevent deselected) for validation purpose. used below approach.
private async void categoryItemsGV_ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as ProductOptionLineModel;
await _viewModel.DialogService("FirstRequireMinOption", "", true);
GridView gv = sender as GridView;
gv.SelectedItems.Add(item);
}
I am writing a simple addressbook example application in WPF in which I have a listview that holds the contacts as User objects, but each item is represented with a TextBlock only showing the name.
What I want to achieve is that a user can drag the item onto a "group". Groups are presented on the left hand side of the window. It is a simple grid column with several TextBlock items.
My relevant codebehind:
/** Display Contact in the contact pane**/
private void lstItemContact_MouseDown(object sender, MouseButtonEventArgs e)
{
ListViewItem item = (ListViewItem)sender;
User selectedUser = (User) item.Content;
DragDrop.DoDragDrop(lstContacts, item, DragDropEffects.Move);
contactPane.Fullname = selectedUser.Name;
contactPane.Email = selectedUser.Mail;
}
private void tbFavouritesDrop_Drop(object sender, DragEventArgs e)
{
User dropped_user = (User)sender;
MessageBox.Show(dropped_user.Name);
}
And the XAML:
<ListView x:Name="lstContacts" Width="250" Grid.Row="1" Grid.Column="1">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock x:Name="lstItemContact" FontWeight="Bold" FontSize="14" Text="{Binding Name}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="lstItemContact_MouseDown" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
<TextBlock AllowDrop="True" Drop="tbFavouritesDrop_Drop" Name="tbFavouritesDrop">
<Border CornerRadius="3" Background="OrangeRed" Height="7" Width="7" VerticalAlignment="Center" Margin="0 0 2 5"/>
<Label FontFamily="Segoe UI Light" FontSize="14" Padding="0">Favourites</Label>
</TextBlock>
Once I drag the Item onto the "Favourites" Group I get the following error:
Additional information: Unable to cast object of type 'System.Windows.Controls.TextBlock' to type 'AddressBook1.User'
I am not sure what the exact problem is? Is the problem, that my listview item is a textblock ? The item I am sending is a User Object, and that reaches tbFavouritesDrop_Drop as well.
EDIT 1:
I have changed my Drop event handler to:
private void tbFavouritesDrop_Drop(object sender, DragEventArgs e)
{
TextBlock item = (TextBlock)sender;
MessageBox.Show(item.Text);
}
No exception is thrown, however, the .Text property is empty.
Ok, I found a solution after going crazy from another thread: WPF Drag and Drop - Get original source info from DragEventArgs
Which leaves me with:
/** Display Contact in the contact pane**/
private void lstItemContact_MouseDown(object sender, MouseButtonEventArgs e)
{
ListViewItem item = (ListViewItem)sender;
User selectedUser = (User) item.Content;
contactPane.Fullname = selectedUser.Name;
contactPane.Email = selectedUser.Mail;
}
private void lstItemContact_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
if (e.Source != null)
{
User selectedItem = (User) lstContacts.SelectedItem;
DragDrop.DoDragDrop(lstContacts, selectedItem, DragDropEffects.Move);
}
}
}
private void tbFavouritesDrop_Drop(object sender, DragEventArgs e)
{
User selectedUser = e.Data.GetData("AddressBook1.User") as User;
MessageBox.Show(selectedUser.Name);
}
I hope that helps someone else. The point here was to use e.Data.GetData("AddressBook1.User") and not work with the sender.
I have a TextBox inside a ListBoxItem which is disabled so I can drag and drop it in the ListBox.
Now once I double click it I want it to be Enabled so I can edit the text and when I'm done I want it do be disabled again to do drag and drop.
I have the MouseDoubleClick event on the ListBoxItem but I can't get access to the TextBox. Can anybody tell me how to achieve this.
at the moment textBox is not recognized in codebehind. seems like I don't get access to it the way I'm trying it.
XAML
<ListBox Name="Locations" Cursor="Hand" HorizontalAlignment="Left" Height="351" Margin="10,48,0,0" VerticalAlignment="Top" Width="285" ItemsSource="{Binding Locations}" IsSynchronizedWithCurrentItem="True" dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True" SelectedItem="{Binding SelectedItem}">
<ListBox.InputBindings>
<KeyBinding Key="Delete" Command="{Binding DeleteLocationCommand}" />
</ListBox.InputBindings>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>
<EventSetter Event="LostFocus" Handler="ListBoxItem_LostFocus"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Name="textBox" Text="{Binding Path=Name}" IsHitTestVisible="False" Width="270" Background="Transparent" BorderThickness="0" Margin="2"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In View
private void ListBoxItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
ListBoxItem item = sender as ListBoxItem;
textBox.IsReadOnly = false;
Locations.textBox.Background = Brushes.White;
textBox.SelectAll();
Cursor = Cursors.IBeam;
}
private void ListBoxItem_LostFocus(object sender, RoutedEventArgs e)
{
textBox.IsReadOnly = true;
}
you can use the ReadOnly property which will prevent the user from making any changes to the text:
texBox.ReadOnly = true;
and
private void changeText(object sender, EventArgs e)
{
(sender as TextBox).ReadOnly = false;
}