For about three hours, I've been trying to get selected indexes of a multiselect listbox. I tried variety of solutions but they don't work. The final thing I've found is the following;
for (int i = 0; i < this.myListBox.Items.Count; i++)
{
ListBoxItem currentItem = this.myListBox.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
if (currentItem != null && currentItem.IsSelected)
{
ApplicationManager.Instance.getContactManager().addToIndexes(i);
}
}
This seems to work but when I scroll-down in the list for example, listboxitem of previously selected items returns null. How can I accomplish this task?
As per my understanding of your question you require selected index...
so you have to use List box tap event and than find selected index
for example
private void mylistbox_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
List<ClsReportId> lstrptId = new List<ClsReportId>();
ListBox lst = (ListBox)sender;
int i = lst.SelectedIndex;
if (lst.SelectedValue == null)
{
}
else
{
ClsGetSubmittedReport cls = (ClsGetSubmittedReport)lst.SelectedValue;
reportId = cls.ReportId1.ToString();
}
}
Hope it will help you
Thanks
Related
I'm showing a set of pictures in a page. I use a GridView to show the pictures. However, when the user resizes the screen to make it narrow, I switch to a ListView.
The problem now is synchronizing the scroll position for the two lists. My approach to the solution is,
1. Get the first visible item of the first list.
2. Scroll the second list to that item using ScrollIntoView
However I'm unable to see any property in GridView/ListView that gives me the first information. Any ideas?
Also any other ways of doing this are appreciated.
That seems to be just about the way I would first try to do it. You can use the ItemsPanelRoot property of the GridView/ListView and get the Children of the panel, then use TransformToVisual().TransformPoint() relative to the list control on each child to find the first one that is visible.
The one gotcha I can think of is when ScrollIntoView() would scroll the item that was first in view port in one list to show as last in view in the other one. Maybe you could get the ScrollViewer from the template of the list control (e.g. by using VisualTreeHelper) and scroll to the beginning of the list first?
The most simple way to do it all might be to just scroll to the same relative offset in the list coming into view as the one going out. It might not be very precise, but it could work.
You could even do a nice animated transition of elements in one list into the elements in the other one.
*Update
I asked around and it seems like I forgot that the default panels in GridView and ListView - the ItemsWrapGrid and ItemsStackPanel contain a FirstVisibleIndex property that could be used to get the object and then call ScrollIntoView() on the list control, which in turns takes a ScrollIntoViewAlignment enum you can use to say you want the scrolled-to-item to be the first visible (aligned to the leading edge).
*Update 2
For ListViewBase - you can also use the ListViewPersistenceHelper to get and set relative offsets.
This upcoming update to WinRT XAML Toolkit might be helpful as it would allow you to simply call: gridView.SynchronizeScrollOffset(listView); or vice versa.
public static class ItemsControlExtensions
{
public static ScrollViewer GetScrollViewer(this ItemsControl itemsControl)
{
return itemsControl.GetFirstDescendantOfType<ScrollViewer>();
}
public static int GetFirstVisibleIndex(this ItemsControl itemsControl)
{
// First checking if no items source or an empty one is used
if (itemsControl.ItemsSource == null)
{
return -1;
}
var enumItemsSource = itemsControl.ItemsSource as IEnumerable;
if (enumItemsSource != null && !enumItemsSource.GetEnumerator().MoveNext())
{
return -1;
}
// Check if a modern panel is used as an items panel
var sourcePanel = itemsControl.ItemsPanelRoot;
if (sourcePanel == null)
{
throw new InvalidOperationException("Can't get first visible index from an ItemsControl with no ItemsPanel.");
}
var isp = sourcePanel as ItemsStackPanel;
if (isp != null)
{
return isp.FirstVisibleIndex;
}
var iwg = sourcePanel as ItemsWrapGrid;
if (iwg != null)
{
return iwg.FirstVisibleIndex;
}
// Check containers for first one in view
if (sourcePanel.Children.Count == 0)
{
return -1;
}
if (itemsControl.ActualWidth == 0)
{
throw new InvalidOperationException("Can't get first visible index from an ItemsControl that is not loaded or has zero size.");
}
for (int i = 0; i < sourcePanel.Children.Count; i++)
{
var container = (FrameworkElement)sourcePanel.Children[i];
var bounds = container.TransformToVisual(itemsControl).TransformBounds(new Rect(0, 0, container.ActualWidth, container.ActualHeight));
if (bounds.Left < itemsControl.ActualWidth &&
bounds.Top < itemsControl.ActualHeight &&
bounds.Right > 0 &&
bounds.Bottom > 0)
{
return itemsControl.IndexFromContainer(container);
}
}
throw new InvalidOperationException();
}
public static void SynchronizeScrollOffset(this ItemsControl targetItemsControl, ItemsControl sourceItemsControl, bool throwOnFail = false)
{
var firstVisibleIndex = sourceItemsControl.GetFirstVisibleIndex();
if (firstVisibleIndex == -1)
{
if (throwOnFail)
{
throw new InvalidOperationException();
}
return;
}
var targetListBox = targetItemsControl as ListBox;
if (targetListBox != null)
{
targetListBox.ScrollIntoView(sourceItemsControl.IndexFromContainer(sourceItemsControl.ContainerFromIndex(firstVisibleIndex)));
return;
}
var targetListViewBase = targetItemsControl as ListViewBase;
if (targetListViewBase != null)
{
targetListViewBase.ScrollIntoView(sourceItemsControl.IndexFromContainer(sourceItemsControl.ContainerFromIndex(firstVisibleIndex)), ScrollIntoViewAlignment.Leading);
return;
}
var scrollViewer = targetItemsControl.GetScrollViewer();
if (scrollViewer != null)
{
var container = (FrameworkElement) targetItemsControl.ContainerFromIndex(firstVisibleIndex);
var position = container.TransformToVisual(scrollViewer).TransformPoint(new Point());
scrollViewer.ChangeView(scrollViewer.HorizontalOffset + position.X, scrollViewer.VerticalOffset + position.Y, null);
}
}
}
I'm using 2 comboboxes to filter a dataGrid that has been populated via csv file. The first combobox filters the columns and works fine:
//Listener and function for when the Agreement ID is selected
agreement_cb.addEventListener(Event.CHANGE, agreement);
function agreement(event:Event):void
{
//get the number of columns
var columnCount:Number = myGrid.getColumnCount();
for (var i:int=0; i<columnCount; i++)
{
myGrid.getColumnAt(i).visible = false;
}
var columnNumber:Number = agreement_cb.selectedItem.data;
myGrid.getColumnAt(columnNumber).visible = true;
myGrid.getColumnAt(0).visible = true;
myGrid.columns[0].width = 200;
}
But I can't find anything on how to get the same type of function to hide all of the rows except the one they select from the second drop-down (codes_cb).
Any help is appreciated...
UPDATE:
loadedData = myLoader.data.split(/\r\n|\n|\r/);
loadedData.pop();
for (var i:int=0; i<loadedData.length; i++)
{
var rowArray:Array = loadedData[i].split(",");
loadedData[i] = {"SelectAgreement":rowArray[0],"KSLTPROF0057":rowArray[1] .........};
}
loadedData.shift();
myGrid.columns = ["SelectAgreement", "KSLTPROF0057", ......];
import fl.data.DataProvider;
import fl.controls.dataGridClasses.DataGridColumn;
myGrid.dataProvider = new DataProvider(loadedData);
A DataGrid always shows all objects in its dataProvider, so to hide rows, you need to hide the data objects. Some classes that work as dataProviders have this functionality built in that makes this really easy (Any Class that implements IList can be operate as a dataProvider), however fl.data.DataProvider is not one of those classes.
So I will provide answers using both, if you can, I highly recommend using mx.collections.ArrayCollection over fl.data.DataProvider.
Section 1: fl.data.DataProvider
For this I'm assuming that your loadedData array is a class property, not declared in a function.
function agreement(event:Event):void
{
//your existing code here
var dataProvider:DataProvider = MyGrid.dataProvider as DataProvider;//recover the dataprovider
dataProvider.removeAll();//remove all rows
for (var x:int = 0; x<loadedData.length; x++)
{
if (loadedData[x] == "SELECTION MATCH") //insert here your selection criteria
{
dataProvider.addItem(loadedData[x]); //add it back into the dataProvider
}
}
}
function resetFilter():void
{
var dataProvider:DataProvider = MyGrid.dataProvider as DataProvider;//recover the dataprovider
dataProvider.removeAll(); //prevent duplication
dataProvider.addItems(loadedData);//reload all rows
}
Section 2: mx.collections.ArrayCollection
My reasoning for recommending this is because ArrayCollection already has the functions to do this without the risk of data being lost by objects losing scope, it also reduces the amount of code/operations you need to do. To do this we use ArrayCollection.filterFunction & ArrayCollection.refresh() to filter the "visible array" without changing the source.
private var dataProvider:ArrayCollection = new ArrayCollection(loadedData);
MyGrid.dataProvider = dataProvider;
function agreement(event:Event):void
{
//your existing code here
dataProvider.filterFunction = myFilterFunction;//use my filter
dataProvider.refresh();//refresh the visible list using new filter/sort
}
function resetFilter():void
{
dataProvider.filterFunction = null;//clear filter
dataProvider.refresh();//refresh the visible list using new filter/sort
}
function myFilterFunction(item:Object):Boolean
{
if (item == "SELECTION MATCH") return true;//insert your selection criteria here
else return false;
}
the filterFunction accepts a function and uses it to test each object in the ArrayCollection, the function has to return a Boolean, true for "Yes, display this object" and false for "Do not diplay".
While working on Windows Phone 8 app, we need to restrict user on navigating pivot.
For example, only first two items are available until user make his selection on second item, then third is unlocked, and so on.
I've tried several approaches, and all of them stumble on one thing - setting pivot.SelectedIndex (or pivot.SelectedItem) inside event handler does not changing visual representation of pivot.
What is missing in my approach?
Here is sample code, from one of variants I've tried...
private void ReservationPivot_UnloadingPivotItem(object sender, PivotItemEventArgs e)
{
if (previousSelectedIndex != ((Pivot)sender).Items.IndexOf(e.Item) && !pivotRedirect)
previousSelectedIndex = ((Pivot)sender).Items.IndexOf(e.Item);
else if (previousSelectedIndex == ((Pivot)sender).Items.IndexOf(e.Item))
return;
object tmp;
PhoneApplicationService.Current.State.TryGetValue("PickupAddress", out tmp);
if (e.Item == ((Pivot)sender).Items[1] && tmp == null && !pivotRedirect)
{
MessageBox.Show("Please, select pickup point!");
pivotRedirect = true;
((Pivot)sender).SelectedIndex = previousSelectedIndex;
((Pivot)sender).SelectedItem = ((Pivot)sender).Items[1];
return;
}
PhoneApplicationService.Current.State.TryGetValue("DropOffAddress", out tmp);
if (e.Item == ((Pivot)sender).Items[2] && tmp == null && !pivotRedirect)
{
MessageBox.Show("Please, select dropoff point!");
pivotRedirect = true;
((Pivot)sender).SelectedIndex = previousSelectedIndex;
((Pivot)sender).SelectedItem = ((Pivot)sender).Items[2];
return;
}
if (pivotRedirect)
{
if (((Pivot)sender).SelectedIndex != previousSelectedIndex)
{
pivotRedirect = false;
((Pivot)sender).SelectedIndex = previousSelectedIndex;
}
}
}
Dont have access to visual now but did you try set visible of third pivot item to collapsed and change it to visible when user will select dropooff point ?
how to compare two arraycollection
collectionArray1 = ({first: 'Dave', last: 'Matthews'},...........n values
collectionArray = ({first: 'Dave', last: 'Matthews'},...........n values
how to compare..if equal just alert nochange if not alert chaged
If you just want to know if they are different from each other, meaning by length, order or individual items, you can do the following, which first checks to see if the lengths are different, then checks to see if the individual elements are different. This isn't terribly reusable, it's left as an exercise for the reader to split this apart into cleaner chunks :)
public function foo(coll1:ArrayCollection, coll2:ArrayCollection):void {
if (coll1.length == coll2.length) {
for (var i:int = 0; i < coll1.length; i++) {
if (coll1[i].first != coll2[i].first || coll1[i].last != coll2[i].last) {
Alert.show("Different");
return;
}
}
}
Alert.show("Same");
}
/* elements need to implement valueOf
public function valueOf():Object{}
*/
public static function equalsByValueOf(
first:ArrayCollection,
seconde:ArrayCollection):Boolean{
if((first==null) != (seconde==null) ){
return false;
}else if(!first && !seconde){
return false;
}
if(first.length!=seconde.length){
return false;
}
var commonLength:int = first.length;
var dictionary:Dictionary = new Dictionary();
for(var i:int=0;i<commonLength;i++){
var item1:Object = first.getItemAt(i);
var item2:Object = seconde.getItemAt(i);
dictionary[item1.valueOf()]=i;
dictionary[item2.valueOf()]=i;
}
var count:int = 0;
for (var key:Object in dictionary)
{
count++;
}
return count==commonLength;
}
/* valueOf sample
* something like javaObject.hashCode()
* use non changing fields(recommended)
*/
public function valueOf():Object{
return "_"+nonChangeField1+"_"+nonChangeField2+"...";
}
I was going to say this.
if(collectionArray === collectionArray1)
But that wont work (not triple = signs). As === is used to see classes.
I would write a function called check if object exists in array.
Create an array to hold elements that are not found. eg notFound
in Collection1 go through all the element and see if they exist in Collection2, if an element does not exist, add it to the notFound array. Use the function your created in step1
Now check Collection2, if an element is not found add it to the notFound array.
There is no 5.
Dude, use the mx.utils.ObjectUtil... the creators of actionscript have already thought about this.
ObjectUtil.compare(collection1, collection2) == 0;
I have a selectbox on a form - which I've turned in to a list box by putting
<select id="Select1" name="D1" size="5" style="width: 220px">
I'm filling this select/listbox with values...
When I post the form how can I get all the values in the select box..is this possible or am I only able to get one that has been selected.
Trouble is I want all the values in the select (I'm not selecting any as such)
Any ideas?
Before submitting the form you can use some JavaScript to pull the items out of the select and put them into a hidden text field (as a delimited string)
For example, you can get the values using
var select1 = document.getElementById('select1');
var values = new Array();
for(var i=0; i < select1.options.length; i++){
values.push(select1.options[i].value);
}
var allValues = values.join(";");
alert(allValues);
Hope that helps.
How are you adding the values to the list box? Are they static or are they pulled from a database.
If you're pulling from the database I would create a function that you use to get the data and bind to the list box.
Then use that same function when you want to get those values after the post. You may have to use some hidden fields to pass along any parameters you use to get the values for the list box in the first place.
example:
function get_models_for_make(int make_id)
mydata_rs = SELECT name, id FROM models WHERE make_id = make_id
return mydata_rs
end
so you could use this data to bind the objects to your listbox and also use it to get the values later that you did bind to your list box.
for (int i = source.Items.Count - 1; i >= 0; i--)
{
ListItem item = source.Items[i];
if (moveAllItems)
item.Selected = true;
if (item.Selected)
{
// if the target already contains items, loop through
// them to place this new item in correct sorted order
if (target.Items.Count > 0)
{
for (int j = 0; j < target.Items.Count; j++)
{
if (target.Items[j].Text.CompareTo(item.Text) > 0)
{
target.Items.Insert(j, item);
item.Selected = false;
break;
}
}
}
// if item is still selected, it must be appended
if (item.Selected)
{
target.Items.Add(item);
item.Selected = false;
}
// remove the item from the source list
source.Items.Remove(item);
}
}