Tie vector item with listview item - visual-studio-2010

How to tie the vector item with listview item? When the listview item is selected and for example, clicked on the delete button, I want to get the item pointer of my vector which ties with selected item in listview, and use function like this:
class x
{
int a;
}
void Delete(vector<x*> vec, x* item)
{
for(int i=0; i < vec.size(); i++)
{
if (vec[i] == item)
vec.erase(i):
}
}
int main()
{ vector<x*> vec;
//selecting item in list view and click the delete button
Delete(vec, /*get item from listview*/);
}
And I need to do another function with this selected item.

Related

CharmListView Infinite Scroll

I need basically an event that triggers at each 200 records loaded, so more data can be loaded until the end of data.
I tried to extend CharmListCell and using the method updateItem like this:
#Override
public void updateItem(Model item, boolean empty) {
super.updateItem(item, empty);
currentItem = item;
if (!empty && item != null) {
update();
setGraphic(slidingTile);
} else {
setGraphic(null);
}
System.out.println(getIndex());
}
But the System.out.println(getIndex()); method returns -1;
I would like to call my backend method when the scroll down gets the end of last fetched block and so on, until get the end of data like the "infinite scroll" technique.
Thanks!
The CharmListCell doesn't expose the index of the underlying listView, but even if it did, that wouldn't be of much help to find out if you are scrolling over the end of the current list or not.
I'd suggest a different approach, which is also valid for a regular ListView, with the advantage of having the CharmListView features (mainly headers and the refresh indicator).
This short sample, created with a single view project using the Gluon IDE plugin and Charm 5.0.0, shows how to create a CharmListView control, and fill it with 30 items at a time. I haven't provided a factory cell, nor the headers, and for the sake of simplicity I'm just adding consecutive integers.
With a lookup, and after the view is shown (so the listView is added to the scene) we find the vertical ScrollBar of the listView, and then we add a listener to track its position. When it gets closer to 1, we simulate the load of another batch of items, with a pause transition that represents a heavy task.
Note the use of the refresh indicator. When new data is added, we scroll back to the first of the new items, so we can keep scrolling again.
public class BasicView extends View {
private final ObservableList<Integer> data;
private CharmListView<Integer, Integer> listView;
private final int batchSize = 30;
private PauseTransition pause;
public BasicView() {
data = FXCollections.observableArrayList();
listView = new CharmListView<>(data);
setOnShown(e -> {
ScrollBar scrollBar = null;
for (Node bar : listView.lookupAll(".scroll-bar")) {
if (bar instanceof ScrollBar && ((ScrollBar) bar).getOrientation().equals(Orientation.VERTICAL)) {
scrollBar = (ScrollBar) bar;
break;
}
}
if (scrollBar != null) {
scrollBar.valueProperty().addListener((obs, ov, nv) -> {
if (nv.doubleValue() > 0.95) {
addBatch();
}
});
addBatch();
}
});
setCenter(new VBox(listView));
}
private void addBatch() {
listView.setRefreshIndicatorVisible(true);
if (pause == null) {
pause = new PauseTransition(Duration.seconds(1));
pause.setOnFinished(f -> {
int size = data.size();
List<Integer> list = new ArrayList<>();
for (int i = size; i < size + batchSize; i++) {
list.add(i);
}
data.addAll(list);
listView.scrollTo(list.get(0));
listView.setRefreshIndicatorVisible(false);
});
} else {
pause.stop();
}
pause.playFromStart();
}
}
Note also that you could benefit from the setOnPullToRefresh() method, at any time. For instance, if you add this:
listView.setOnPullToRefresh(e -> addBatch());
whenever you go to the top of the list and drag it down (on a mobile device), it will make another call to load a new batch of items. Obviously, this is the opposite behavior as the "infinite scrolling", but it is possible as well with the CharmListView control.

Update MultiselectList selected items

I'm using MultiselectList from Controls.Toolkit. I use it as a favourite selector. I have a list with items, I select the favourites and the next time I open the selection bar I would like to see my favourites already selected. When IsSelectionEnabledChanged event occurs, if IsSelectionEnabled is true (the selection bar is opened) I try to add my favourites to the list's SelectedItems. Here is a code snippet:
private void multiSelectList_IsSelectionEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (multiSelectList.IsSelectionEnabled)
{
foreach (var favourite in FavouritesList)
{
multiSelectList.SelectedItems.Add(multiSelectList.Items.Where(i => ((MyModel)i).id == favourite.id).FirstOrDefault());
}
}
}
I have tested this solution and I found out that the layout does not update the entire list that's why I'm not seeing the items as selected (but they are). Not even the actual visible items in the list. After scrolling for a bit and scrolling back, the selection appears! I've tried to use multiSelectList.UpdateLayout() method programatically but it did not solve it.
I wonder if it is a visualization problem or a CheckBox binding problem (the selection uses CheckBox on the side).
The SelectedItems is just a List<object>, it doesn’t raise any events when you update it.
To update your items manually, you could do something like following instead (untested code):
private void multiSelectList_IsSelectionEnabledChanged( object sender, DependencyPropertyChangedEventArgs e )
{
if( !multiSelectList.IsSelectionEnabled )
return;
var dictSelected = FavouritesList.ToDictionary( f => f.id, f => true );
for( int i = 0; i < multiSelectList.Items.Count; i++ )
{
MyModel m = (MyModel)multiSelectList.Items[ i ];
if( !dictSelected.ContainsKey( m.id ) )
continue; // Not selected
MultiselectItem item = (MultiselectItem)multiSelectList.ItemContainerGenerator.ContainerFromIndex( i );
if( null != item )
item.IsSelected = true; // This should add the item into the SelectedItems collection.
else
multiSelectList.SelectedItems.Add( m ); // The item is virtualized and has no visual representation yet.
}
}

Get Pixel Position of Item or Cell Height in Treeview

In a GTK# application, I am using a TreeView inside a ScrolledWindow, and try to find the position of an item inside the TreeStore to draw lines starting from that item in Cairo. For now, I am using a hard coded value for cell height, which works for few items, but when other font sizes are used or the item list gets longer, there is a visible offset. Is there a method to get the cell height of a TreeView, or another way to get the vertical position of an item in the TreeStore?
Here is the method, that I currently use:
int GetYPositionForPort (TreeView tree, TreeStore store, Port selectedPort)
{
// Is there a way to get the cell height?
int cellHeight = 24;
// We start in the middle of the first Treeview item
int position = cellHeight / 2;
ScrolledWindow treeParent = tree.Parent as ScrolledWindow;
if (treeParent != null) {
position -= Convert.ToInt32 (treeParent.Vadjustment.Value);
}
TreeIter clientIter;
TreeIter portIter;
if (store.GetIterFirst (out clientIter)) {
do {
if (store.IterHasChild (clientIter)
&& tree.GetRowExpanded (store.GetPath (clientIter))) {
if (store.IterChildren (out portIter, clientIter)) {
do {
position += cellHeight;
} while (((Port)store.GetValue(portIter, 0) != selectedPort
|| (Client)store.GetValue(clientIter, 0) != selectedPort.Client)
&& store.IterNext(ref portIter));
}
}
//Necessary because the first Treeview item only counts as 1/2 cell height.
if (((Client)store.GetValue (clientIter, 0)) == selectedPort.Client) {
break;
}
position += cellHeight;
} while (store.IterNext(ref clientIter));
}
return position;
}
You can see the error on the bottom of the screenshot where the lines are not aligned with the items in the TreeView:
Reading the documentation, I have come up with the following ugly piece of code:
int GetCellHeight (TreeView tree)
{
if (_cellHeight > 0) {
return _cellHeight;
}
int offsetX;
int offsetY;
int cellWidth;
Gdk.Rectangle rectangle = new Gdk.Rectangle ();
TreeViewColumn column = tree.GetColumn (0);
// Getting dimensions from TreeViewColumn
column.CellGetSize(rectangle, out offsetX, out offsetY,
out cellWidth, out _cellHeight);
// And now get padding from CellRenderer
CellRenderer renderer = column.CellRenderers[0];
_cellHeight += (int)renderer.Ypad;
return _cellHeight;
}
This is what it looks like now:

How to implement Hold in Listbox?

If hold the listbox, I want to get listbox index.
This is my code:
<ListBox Margin="0,0,-12,0"
Hold="holdlistbox"
x:Name="listbox"
SelectionChanged="listbox_SelectionChanged"
SelectedIndex="-1">
</ListBox>
private void holdlistbox(object sender, System.Windows.Input.GestureEventArgs e)
{
//How to get ListBox index here
}
If anyone knows help me to do this.
e.OriginalSource will get you the actual control that was held (the top-most control directly under your finger). Depending on your ItemTemplate and where you hold then this could be any of the controls in the item. You can then check the DataContext of this control to get the object that is bound to that item (going by your comment this will be an ItemViewModel object):
FrameworkElement element = (FrameworkElement)e.OriginalSource;
ItemViewModel item = (ItemViewModel)element.DataContext;
You can then get the index of this item in the items collection:
int index = _items.IndexOf(item);
If you want to get the ListBoxItem itself you will need to use the VisualHelper class to search the parent heirarchy. Here is an enxtension method that I use to do this:
public static T FindVisualParent<T>(this DependencyObject obj) where T : DependencyObject
{
DependencyObject parent = VisualTreeHelper.GetParent(obj);
while (parent != null)
{
T t = parent as T;
if (t != null)
{
return t;
}
parent = VisualTreeHelper.GetParent(parent);
}
return null;
}
I'm not sure if you need this (I couldn't be sure from your comment) but you can then do the following to get the context menu:
FrameworkElement element = (FrameworkElement)e.OriginalSource;
ListBoxItem listItem = element.FindVisualParent<ListBoxItem>();
ContextMenu contextMenu = ContextMenuService.GetContextMenu(listItem);
This assumes that the ContextMenu is attached to the ListBoxItem, if not then you need to search for a different control in the parent heirarchy.
var selectedIndex = (sender as ListBox).SelectedIndex;

how to access a ListBox inside a Pivot in windows phone 7?

i have a a Pivot that has a ListBox defined as its Pivot.ItemTemplate as the following.
<controls:Pivot x:Name="pivot">
<controls:Pivot.ItemTemplate>
<DataTemplate>
<ListBox x:Name="listBox">
...
</ListBox>
</DataTemplate>
</controls:Pivot.ItemTemplate>
</controls:Pivot>
how do i programmatically access the corresponding ListBox control corresponding to the Pivot.SelectedItem or Pivot.SelectedIndex?
i tried something similar to this link http://www.windowsphonegeek.com/tips/how-to-access-a-control-placed-inside-listbox-itemtemplate-in-wp7.
var count = VisualTreeHelper.GetChildrenCount(pivotItem);
for(int i=0; i < count; i++) {
var child = VisualTreeHelper.GetChild(pivotItem, i);
if(child is ListBox) {
//do something
} else {
Debug.WriteLine(child.GetType());
}
}
for some reason, i get System.Windows.Controls.Grid on the Debug.WriteLine.
the reason why i need to get a handle or access the ListBox inside the Pivot (that is currently on display/selected), is because i need to reset its view (scroll it back to the top). the ListBox is data bound to ObservableCollection, and when i update the collection, the scroll position needs to be placed back to the top; otherwise, everything works (data binding/visual display), except now the view is stuck in the middle or where the user currently is. if there's an easier way to do this without getting a handle on the ListBox, i'm open to that solution as well.
just in case anyone is interested, i tinkered and came up with something that works specifically for my case. the code is below. basically, i had to get the PivotItem first.
PivotItem pivotItem = pivot.ItemContainerGenerator.ContainerFromItem(myObject) as PivotItem;
i then created a local variable to store the ListBox (if it's found) and recursed the tree view model.
ListBox listBox = null;
Recurse(pivotItem, ref listBox);
and my Recurse function looks like the following.
private void Recurse(DependencyObject obj, ref ListBox listBox) {
if(obj is ListBox) {
listBox = obj as ListBox;
return;
}
var count = VisualTreeHelper.GetChildrenCount(obj);
for(int i=0; i < count; i++) {
var child = VisualTreeHelper.GetChild(obj, i);
Recurse(child, ref listBox);
}
}
try:
(Listbox)VisualTreeHelper.GetChild((pivot.SelectedItem as PivotItem), 0);
Looks like this was a while back, but this is what worked for me:
First get the PivotItem:
PivotItem pivotItem = Pivot.ItemContainerGenerator.ContainerFromItem(Pivot.SelectedItem) as PivotItem;
Then get the first child, a ListBox, from the PivotItem:
private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject {
var count = VisualTreeHelper.GetChildrenCount(parentElement);
if (count == 0)
return null;
for (int i = 0; i < count; i++) {
var child = VisualTreeHelper.GetChild(parentElement, i);
if (child != null && child is T) {
return (T)child;
} else {
var result = FindFirstElementInVisualTree<T>(child);
if (result != null)
return result;
}
}
return null;
}
Then call:
ListBox listBox = FindFirstElementInVisualTree<ListBox>(pivotItem);
use StackPanel inside your ListBox
this link may help you
http://blogs.msdn.com/b/oren/archive/2010/11/08/wp7-silverlight-perf-demo-1-virtualizingstackpanel-vs-stackpanel-as-a-listbox-itemspanel.aspx

Resources