Select ListBoxItem under RightTapped event - c#

I have the following event right now
private void contactGrid_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
if (contactGrid.SelectedIndex >= 0)
{
FrameworkElement senderElement = sender as FrameworkElement;
MenuFlyout menu = new MenuFlyout();
MenuFlyoutItem item1 = new MenuFlyoutItem() { Text = "Edit Contact" };
MenuFlyoutItem item2 = new MenuFlyoutItem() { Text = "Comfirm" };
MenuFlyoutSubItem item2a = new MenuFlyoutSubItem() { Text = "Remove Contact" };
item1.Click += new RoutedEventHandler(EditContactClicked);
item2.Click += new RoutedEventHandler(RemoveContactClicked);
item2a.Items.Add(item2);
menu.Items.Add(item1);
menu.Items.Add(item2a);
menu.ShowAt(senderElement, e.GetPosition(contactGrid));
}
}
This works fine and creates the right click context menu at the mouse pointer on top of a listbox item, but only if it has been selected first. What I can't figure out is how to get the RightTapped event to select the item that was right tapped. I have yet to test this in tablet mode and
I'm currently using a mouse to trigger the right tapped event (by right clicking).
Is the default behaviour of a long press (to trigger a right tap) in tablet mode such that it selects the item anyway?

As far as I understand, contactGrid is your ListBox? I guess you have any kind of List or Collection set as the ItemsSource of the ListBox? Then you can set the SelectedItem property in your right tapped-event like following:
First you need to modify the ItemTemplate, so that RightTapped belongs to a ListBoxItem:
<ListBox x:Name="ContactGrid">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="Transparent" RightTapped="contactGridItem_RightTapped">
<TextBlock Text="{Binding}" />
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And in code (I'm actually wondering that the Flyout is shown above the selectedItem and not above the whole ListBox):
private void contactGridItem_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
FrameworkElement senderElement = sender as FrameworkElement;
// Now you can get the tapped Item from the DataContext and set is as selected
contactGrid.SelectedItem = senderElement.DataContext;
if (contactGrid.SelectedIndex >= 0)
{
MenuFlyout menu = new MenuFlyout();
MenuFlyoutItem item1 = new MenuFlyoutItem() { Text = "Edit Contact" };
MenuFlyoutItem item2 = new MenuFlyoutItem() { Text = "Comfirm" };
MenuFlyoutSubItem item2a = new MenuFlyoutSubItem() { Text = "Remove Contact" };
item1.Click += new RoutedEventHandler(EditContactClicked);
item2.Click += new RoutedEventHandler(RemoveContactClicked);
item2a.Items.Add(item2);
menu.Items.Add(item1);
menu.Items.Add(item2a);
menu.ShowAt(senderElement, e.GetPosition(contactGrid));
}
}
(not tested, but that's how I would solve it)

Related

Button for checkbox worked once

I have created checkboxes. When user checks an item, the item is displayed in datagridview.
This is the code of checkbox in XAML
<Grid>
<ListBox HorizontalAlignment="Stretch" Name="APIList"
ItemsSource="{Binding Tables[0]}"
ItemTemplate="{StaticResource NameColumnTemplate}"
SelectionChanged="lst_SelectionChanged" CheckBox.Click="lst_SelectionChanged"/>
<Button Content="listbox" Name="btnShowSelectedItems"
Click="btnShowSelectedItems_Click" />
</Grid>
This is the code behind
private void btnShowSelectedItems_Click(object sender, RoutedEventArgs e)
{
string path, name;
int i = 0,c=0, result;
string[] lines = System.IO.File.ReadAllLines(#"D:\7th semester\FYP\source\repos\dllPaths.txt");
string[] selecteditem = new string[50];
var showapi = APIList.ItemsSource as List<showAPI>;
foreach (var item in showapi)
{
if (item.IsSelected == true)
{
selecteditem[i] = item.apiName;
}
}
}
When user click on button checked items display in table but if user again check more items and again click on button nothing happen and result remain unchanged.
In short this button work only once.

How to add context menu in Windows 10 UWP on ListView Item?

I am working on Windows 10 UWP app and came across a long press menu in Photos app as below
Can someone suggest how to create this type of menu in Windows 10?
I checked PopupMenu control but it only allows 6 options in the menu.I want to create this menu using C# not XAML.
You can use Flyout for this purpose, then in item's datatemplate, define subscripe to event and show your menu. A sample can look like this:
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Holding="Grid_Holding" VerticalAlignment="Stretch">
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem x:Name="EditButton" Text="Edit"/>
<MenuFlyoutItem x:Name="DeleteButton" Text="Delete"/>
<MenuFlyoutSubItem Text="OtherItems">
<MenuFlyoutItem Text="Inside1"/>
<MenuFlyoutItem Text="Inside2"/>
<MenuFlyoutItem Text="Inside3"/>
</MenuFlyoutSubItem>
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
<TextBlock Text="{Binding}" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<x:String>Item 1</x:String>
<x:String>Item 2</x:String>
<x:String>Item 3</x:String>
<x:String>Item 4</x:String>
<x:String>Item 5</x:String>
</ListView>
And the code behind:
private void Grid_Holding(object sender, HoldingRoutedEventArgs e)
{
FrameworkElement senderElement = sender as FrameworkElement;
// If you need the clicked element:
// Item whichOne = senderElement.DataContext as Item;
FlyoutBase flyoutBase = FlyoutBase.GetAttachedFlyout(senderElement);
flyoutBase.ShowAt(senderElement);
}
As a result you should see something like in the picture below.
Some more help you will also find at MSDN.
Edit after comments.
Generally everything you create in XAML can be created in code behind. If you want to create a Flyout, then it can look like this:
private bool startedHolding = false;
private void Grid_Holding(object sender, HoldingRoutedEventArgs e)
{
// simple checkup for holding release for this sample, though this probalby need better handling
startedHolding = !startedHolding;
if (startedHolding)
{
MenuFlyout myFlyout = new MenuFlyout();
MenuFlyoutItem firstItem = new MenuFlyoutItem { Text = "First item" };
MenuFlyoutItem secondItem = new MenuFlyoutItem { Text = "Second item" };
MenuFlyoutSubItem subItem = new MenuFlyoutSubItem { Text = "Other items" };
MenuFlyoutItem item1 = new MenuFlyoutItem { Text = "First sub item" };
MenuFlyoutItem item2 = new MenuFlyoutItem { Text = "Second sub item" };
subItem.Items.Add(item1);
subItem.Items.Add(item2);
myFlyout.Items.Add(firstItem);
myFlyout.Items.Add(secondItem);
myFlyout.Items.Add(subItem);
FrameworkElement senderElement = sender as FrameworkElement;
myFlyout.ShowAt(senderElement);
}
}

WPF - duplicating a stackpanel

i have this (a rough e.g):
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label .../>
<TextBox .../>
<Button Content="Add new input row" ... />
</StackPanel>
</StackPanel>
pretty self explanatory, i want to add a new Horizontal StackPanel with every click on the button..
is that possible?
thank you!
For this XAML above I will do like this:
In the click event handle of every button name "Add new input row", I mean you can use this event for all of buttons.
private void btn_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
StackPanel stkButtonParent = btn.Parent as StackPanel;
StackPanel stkCover = stkButtonParent.Parent as StackPanel;
StackPanel newRow = NewRow();
stkCover.Children.Add(newRow);
}
private StackPanel NewRow() {
StackPanel stk = new StackPanel();
stk.Orientation = Orientation.Horizontal;
Label lbl = new Label();
lbl.Foreground = Brushes.Red; // some attribute
TextBox txt = new TextBox();
txt.Background = Brushes.Transparent; // some attribute
Button btn = new Button();
btn.Content = "Add new row";
btn.Click += btn_Click;
stk.Children.Add(lbl);
stk.Children.Add(txt);
stk.Children.Add(btn);
return stk;
}
Yes it is possible try handling the event like this for example:
// Create your StackPanel.
StackPanel sp = new StackPanel();
sp.Orientation = Orientation.Horizontal;
// Add controls to new StackPanel
// Control con = new Control();
// sp.Children.Add(con);
// Add created control to a previously created (and named) container.
myStackPanel.Children.Add(sp);
If you would like your StackPanel to contain some controls you can also add them to it here.
There is a way to do this via XamlReader as well, but I have never tried it.
Here is a link to a short article:
arcanecode.com

Adding an click event to a programatically added menu item

I am working on a C# WPF project and I am storing some items in an SQLite database, when the program loads, it then retrieves the items from the database and adds the items to the menu. What I then need to do is to allow the user to click on one of the added menu items and something is done based on what was clicked. I can't find anything on how to do this, below is the code for how I am adding the menu item to the menu programatically.
StoredDBConnectionManager storedDbConnectionManager = new StoredDBConnectionManager(Properties.Settings.Default.app_dbPassword);
List<string> connections = storedDbConnectionManager.getStoredConnections();
foreach (string connection in connections)
{
mnuFileDBConnections.Items.Add(connection);
}
Thanks for any help you can provide.
Here's an example:
XAML:
<Menu Height="23" HorizontalAlignment="Left" Name="menu1" VerticalAlignment="Top" Width="200" />
Code behind:
public MainWindow() {
InitializeComponent();
MenuItem item = new MenuItem { Header = "test" };
item.Click += new RoutedEventHandler(item_Click);
menu1.Items.Add(item);
}
public void item_Click(Object sender, RoutedEventArgs e) {
MessageBox.Show("Hello!");
}
There should be a MenuItem control you can instantiate and use the connection as its Header or Content.
MenuItem will then have a Click event handler against it or you can set the command.
Ideally however, you should be retrieving the connections collection, setting it to a property on your model and then have the menu bound to that collection, that way it's a simple matter of making use of an ItemTemplate for the menu.
e.g.
StoredDBConnectionManager storedDbConnectionManager = new StoredDBConnectionManager(Properties.Settings.Default.app_dbPassword);
List<string> connections = storedDbConnectionManager.getStoredConnections();
foreach (string connection in connections)
{
var mi = new MenuItem()
{
Header = connection,
};
mi.Click += ConnectionMenuItemClicked;
mnuFileDBConnections.Items.Add(mi);
}
OR with binding:
<Menu ItemsSource="{Binding Connections}">
<Menu.ItemTemplate>
<DataTemplate>
<MenuItem Header="{Binding}" Click="ConnectionsMenuItem_Clicked">
</MenuItem>
</DataTemplate>
</Menu.ItemTemplate>
</Menu>
foreach(string menuCaption from ...)
{
MenuItem mi=new MenuItem();
mi.Header = meniCaption;
mi.Click += (s,e) =>
{
...
}
}

C# Tie ListView items with objects

Whats the best way to tie ListView item with a object so when i move the item form one listview to another then i would be still able to tell to what object its assigned.
For example, i have object Cards. All these are listed in a allCards ListView. I have another selectedCards ListView and a button what moves selected items from one listview to another. When im done my selection i need to get the list of the Card objects what moved to the selectedCards ListView.
To expand on #CharithJ's answer, this is how you would use the tag property:
ListView allCardsListView = new ListView();
ListView selectedCardsListView = new ListView();
List<Card> allCards = new List<Card>();
List<Card> selectedCards = new List<Card>();
public Form1()
{
InitializeComponent();
foreach (Card selectedCard in selectedCards)
{
ListViewItem item = new ListViewItem(selectedCard.Name);
item.Tag = selectedCard;
selectedCardsListView.Items.Add(item);
}
foreach (Card card in allCards)
{
ListViewItem item = new ListViewItem(card.Name);
item.Tag = card;
allCardsListView.Items.Add(new ListViewItem(card.Name));
}
Button button = new Button();
button.Click += new EventHandler(MoveSelectedClick);
}
void MoveSelectedClick(object sender, EventArgs e)
{
foreach (ListViewItem item in allCardsListView.SelectedItems)
{
Card card = (Card) item.Tag;
//Do whatever with the card
}
}
Obviously you'll need to adapt it to your own code, but that should get you started.
You could use observable collections, and create a datatemplate for your Card class. Then you just bind your ListView to the collection and it does all the work for you. When you add an item to the ObservableCollection the ListView automatically redraws.
using System.Collections.ObjectModel;
<ListView Name="allCardsView" Source="{Binding}">
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type yourXmlns:Card}">
//Your template here
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView Name="selectedCardsView" Source="{Binding}">
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type yourXmlns:Card}">
//Your template here
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
ObservableCollection<Card> allCards = new ObservableCollection<Card>();
ObservableCollection<Card> selectedCards = new ObservableCollection<Card>();
allCardsView.DataContext = allCards;
selectedCardsView.DataContext = selectedCards;
public void ButtonClickHandler(object sender, EventArgs e)
{
if (allCardsView.SelectedItem != null &&
!selectedCards.Contains(allCardsView.SelectedItem))
{
selectedCards.Add(allCardsView.SelectedItem);
}
}
1st way.
Assign the object to the Tag property of the ListViewItem. Get the tags of the selected items.
2nd Way.
Add invisible subItem to the listView that holds the ID of the Card object. Then find the card by using the selected item IDs.
Better use ObjectListView. It is a perfect way to add and use objects with ListView. With features like Hot tracking and easy to use drag and drop your listview becomes lot simpler to manipulate.

Categories