Getting data from event args in ListViewItem click handler - c#

So i have a some ListView populated with data. And i have item click-handler. It looks so
var listview = FindViewById<ListView>(Resource.Id.myList);
listview .ItemClick += OnItemClick;
// populating listview items
MyModel[] someDataArray = GetData();
listview .Adapter = new MyAdapter(this, someDataArray );
....
protected async void OnItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
// here i would like to perfom some actions with instance of MyModel
// associated with current ListView's Item
}
I wanna get the instance of MyModel associated with ListView's Item in OnItemClick event handler but i dont know how i can get this model in this event handler.

There is a Position property on the ItemClickEventArgs. So,
MyModel model = someDataArray[e.Position];

Related

Calling method on SelectionChanged ListBox event with the selected item as parameter

I'm trying to call a method which fills a table with data according to the ListBoxItem that has been selected.
// Setting the ListBoxItems
myListBox.ItemsSource = list;
// Calling the method when the ListBox's selection changes
myListBox.SelectionChanged += LbItem_Select;
The above snippet can't work because the LbItem_Select event handler doesn't get as a parameter the item that is currently selected.
This is the event handler:
private void LbItem_Select(object sender, RoutedEventArgs e)
{
var lbItem = sender as ListBoxItem;
lbItemContent = lbitem.Content.ToString();
// fill the table according to the value of lbItemContent
}
How could I achieve this?
When you work with events, sender is the object related to the event. myListBox.SelectionChanged is an event of the ListBox. So sender is the ListBox, not the item. Try with this:
private void LbItem_Select(object sender, RoutedEventArgs e)
{
var listBox = sender as ListBox;
// Or use myListBox directly if you have the ListBox available here
var item = listBox.SelectedItem;
// Do whatever with the item
}

How to move List View Item from one list to another with drag and drop? UWP C#

I have many List Views in an UWP application and I would want to be able to move one item from one List View to another List View
I know about the AllowDrop or CanDragItems properties and that you need to handle some events for drag and drop to work, although I just don't know how to do it.
If you want to add ListView controls by clicking Add button and move items between ListView controls, please check the following code as a sample. The following code is different from the offical sample, it use ObservableCollection to complete the drag and drop operation. You could drag an item from source ListView item to target ListView, and also drag an item from original target ListView to original source ListView.
You could click the Add button twice and then two ListView with two items are added. You can drag any item from any ListView control to another. If you want to keep the dragged item in the source ListView control, just comment the code dragCollection.Remove(dragedItem as string); .
For example:
private ObservableCollection<string> dragCollection;
private ObservableCollection<string> dropCollection;
private object dragedItem;
private ListView dragListView;
private ListView dropListView;
……
private void AddButton_Click(object sender, RoutedEventArgs e)
{
ListView listView = new ListView();
listView.CanDragItems = true;
listView.CanDrag = true;
listView.AllowDrop = true;
listView.ReorderMode = ListViewReorderMode.Enabled;
listView.CanReorderItems = true;
listView.ItemsSource = new ObservableCollection<string>() { "item1","item2" };
listView.DragItemsStarting += ListView_DragItemsStarting;
//listView.DropCompleted += ListView_DropCompleted;
listView.DragEnter += ListView_DragEnter;
listView.Drop += ListView_Drop;
listView.DragOver += ListView_DragOver;
listView.BorderBrush = new SolidColorBrush(Colors.Red);
listView.BorderThickness = new Thickness(1);
stackPanel.Children.Add(listView);
}
private void ListView_DragOver(object sender, DragEventArgs e)
{
e.AcceptedOperation = DataPackageOperation.Move;
}
private void ListView_Drop(object sender, DragEventArgs e)
{
dropListView = sender as ListView;
if(dropListView!=null)
{
dropCollection = dropListView.ItemsSource as ObservableCollection<string>;
if (dragedItem != null)
{
dropCollection.Add(dragedItem as string);
//If you need to delete the draged item in the source ListView, then use the following code
dragCollection.Remove(dragedItem as string);
dragedItem = null;
}
}
}
private void ListView_DragEnter(object sender, DragEventArgs e)
{
e.AcceptedOperation = (e.DataView.Contains(StandardDataFormats.Text) ? DataPackageOperation.Move : DataPackageOperation.None);
}
private void ListView_DropCompleted(UIElement sender, DropCompletedEventArgs args)
{
var listView = sender as ListView;
if (listView != null)
{
dropListView = listView;
dropCollection = listView.ItemsSource as ObservableCollection<string>;
if(dropListView==dragListView)
{
return;
}
}
}
private void ListView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
var listView = sender as ListView;
if(listView!=null)
{
dragListView = listView;
dragCollection = listView.ItemsSource as ObservableCollection<string>;
if (dropListView == dragListView)
{
return;
}
if(e.Items.Count==1)
{
dragedItem = e.Items[0];
e.Data.RequestedOperation = Windows.ApplicationModel.DataTransfer.DataPackageOperation.Move;
}
}
}
For more information about dragging and dropping, you could refer to the document(https://learn.microsoft.com/en-us/windows/uwp/design/input/drag-and-drop).
Any concerns about the code, please feel free to contact me.
To implement dragging, you must set CanDragItems on the source ListView and AllowDrop on the target ListView. Then, you must handle DragItemsStarting event on the source list. Within this handler you can store the dragged data inside the DragItemsStartingEventArgs.Data property. Afterwards, you handle Drop event on the target list and retrieve the stored item values from the DataPackage using DragEventArgs.DataView.
To see all the moving parts of this in action, I recommend the official UWP samples for drag & drop which are available on GitHub. The first scenario of this sample show dragging items from and to a ListView including reordering support.

BindingSource AddNew() and initializing values

i have a ComponentOne FlexGrid bound to a bindingsource and the bindingsource is bound to a bindinglist collection.
The user clicks an insert button. I call AddNew() on the BindingSource. in the AddingNew() event, i want to initialize the properties in the bindingsource. usually if i want to access the data underlying the grid row i do this
MemberSkill skill = (MemberSkill)MemberSkillBS.Current
skill.SocSecNo = currentMember.SocSecNo;
but when i do this in the AddingNew() event, Current is still pointing to the row with the focus on the grid. how can i access the new item i added to the binding source and initialize it?
The new item becomes the current item after the AddNew has been called.
In your Insert button handler you do:
private void buttonInsert_Click(object sender, EventArgs e)
{
MemberSkill newItem = MemberSkillBS.AddNew() as MemberSkill;
if (newItem != null)
{
MemberSkillBS.Add(newItem);
}
...
}
and in your AddingNew handler you do:
private void MemberSkillBS_AddingNew(object sender, AddingNewEventArgs e)
{
MemberSkill skill = new MemberSkill
{
SocSecNo = MemberSkillBS.Current.SocSecNo
};
e.NewObject = skill;
}

Retain Datagrid multiselection after it is updated

I'm developing a WPF application and use the mvvm light toolkit. My viewmodel consists of a timer which updates an ObservableCollection. Additionally I have a ListCollectionView.
ObservableCollection<MyType> obs = new ObservableCollection<MyType>();
ListCollectionView cView = new ListCollectionView(obs);
public void timer_elapsed(object sender, ElapsedEventArgs e)
{
if(myOperation == add)
obs.InsertItem(0, newObject);
else if(myOperation == remove)
obs[...].Close();
else if(myOperation == modify)
obs[...] = newObject;
}
In my view, I bind a datagrid to the ListCollectionView:
<DataGrid
ItemsSource="{Binding cView}"
AutoGenerateColumns="True"
SelectionUnit="FullRow"
SelectionMode="Extended"
/ >
Whenever the ObservableCollection is changed by one of the operations in the timer, the ListCollectionView is changed as well, and so is the content of the datagrid.
I can select multiple rows between the changes, but as soon as the datagrids content is changed my selections get lost.
How do I retain all of my datagrids selections, even if its content is changed?
Why not just take an account of the selected items before the update? After the updates, repopulate the selected SelectedItems list as needed.
This is a bit of a challenge from an MVVM standpoint, because SelectedItems is not a dependency property. But use your view-viewmodel communication method of choice -- passing view items into the viewmodel, event aggregator, whichever.
Example for completeness:
View model
public Func<IList> GetSelectedItems { get; set; }
public void timer_elapsed(object sender, ElapsedEventArgs e)
{
var previouslySelectedItems = new List<MyType>(GetSelectedItems().OfType<MyType>());
// .... updates
var currentSelectedItems = GetSelectedItems();
foreach (var selected in previouslySelectedItems)
if (!currentSelectedItems.Contains(selected))
currentSelectedItems.Add(selected);
}
View
public MyView()
{
InitializeComonent
Loaded += (sender, args) =>
((MyViewModel)DataContext).GetSelectedItems = () => grid.SelectedItems;
}

Change a selected item in a listview based on the selection in another listview

I have two list views. In the Item command event of the first Listview i am showing the second list view in modal popup using ajaxtoolkit.
protected void lvSelection_ItemCommand(object sender, ListViewCommandEventArgs e)
{
this.lvPopup.Visible = true;
this.lvPopup.DataSource = linqdataSource;
this.lvPopup.DataBind();
this.mdlPopup.Show();
}
Now in the itemcommand event of the second list view I need to change the content of the selected item in the first listview.
Is it possible to do that?
protected void lvPopup_ItemCommand(object sender, ListViewCommandEventArgs e)
{
// Set the text of the first list view item to the selected item
// of the second list view.
lstView1.Items[lstView1.SelectedIndex].Text =
lstView2.Items[lstView2.SelectedIndex].Text
}
I'd think that if you were to set the CommandName of the selector button in the first ListView to "Select" - from the second list view's ItemCommand event, you should be able to alter either the SelectedItemTemplate or the current item for the selected item in the first list.
protected void lvPopup_ItemCommand(object sender, ListViewCommandEventArgs e)
{
lvSelection.SelectedItemTemplate = "<div>woohoo!</div>";
// OR...
lvSelection.Items[lvSelection.SelectedIndex].SkinID = "SomeNewSkinForExample";
mdlPopup.Hide();
}
Have you already tried to dynamically generate the items of the List?
On the event code of the 1st list, clear the Items from the 2nd list and populate it with whatever logic suits you.

Categories

Resources