change databound listbox to longlistselector - c#

I have a Listbox which items can be open & view by following code...
private void AccountsList_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var listBoxItem = AccountsList.ItemContainerGenerator.ContainerFromIndex(AccountsList.SelectedIndex) as ListBoxItem;
var txtBlk = FindVisualChildByType<TextBlock>(listBoxItem, "txtBlkAccountName");
xCa = txtBlk.Text;
NavigationService.Navigate(new Uri(string.Format("/ViewAccount.xaml?parameter={0}&action={1}", a.ToString(), "View"), UriKind.Relative));
}
&
T FindVisualChildByType<T>(DependencyObject element, String name) where T : class
{
if (element is T && (element as FrameworkElement).Name == name)
{
return element as T;
}
int childcount = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < childcount; i++)
{
T childElement = FindVisualChildByType<T>(VisualTreeHelper.GetChild(element, i), name);
if (childElement != null)
{
return childElement;
}
}
return null;
}
now i am implementing longlistselector instead of the listbox.
Long List Selector shows all my items from database but i am having problem while opening an item from this list... i cant use SelectedIndex in this longlistselector PLEASE HELP...

I would suggest you change your workflow. Instead of listening to the Tap event, listen to the SelectionChanged event. From this event you can get the SelectedItem. The SelectItem is the object the Items are bound to.
Example: Your ItemsSource is List each item within the ListBox or LongListSelector is bound to an instance of MyObject. Your "txtBlkAccountName" TextBlock should have it's Text bound to the AccountNumber property of your MyObject class.
private void LongListSelector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var myObj = AccountsList.SelectedItem as MyObject;
if(myObj == null) return;
var accountNum = myObj.AccountNumber;
NavigationService.Navigate(new Uri(string.Format("/ViewAccount.xaml?parameter={0}&action={1}", accountNum, "View"), UriKind.Relative));
// set the selectedItem to null so the page can be navigated to again
// If the user taps the same item
AccountsList.SelectedItem = null;
}

To get the item tapped, place the Tap even inside the ItemTemplate not the List, then you can use the sender property to retrieve the value you want.
Also instead of using FindVisualChildByType to get the value you want you should be able to just use the DataContext to retrieve whatever you want:
private void AccountsItem_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
FrameworkElement element=sender as FrameworkElement ;
Account item= element.DataContext as Account ;
xCa = item.Name;
NavigationService.Navigate(new Uri(string.Format("/ViewAccount.xaml?parameter={0}&action={1}", a.ToString(), "View"), UriKind.Relative));
}

Related

How to trigger the Listview behind when Treeview is click?

I have treeview inside my Listview like below
<ListView x:Name="LvItemDisplay" ItemsSource="{Binding itemDisplayList}" SelectionChanged="LvItemDisplay_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate x:Name="dtItemDisplay">
<TreeView x:Name="TvItemDisplay" Background="Transparent" ItemsSource="{Binding itemDisplayList}" MouseDown="TvItemDisplay_MouseDown_1" SelectedItemChanged="TvItemDisplay_SelectedItemChanged" >
.
.
.
I have click event for both treeview and listview. both of it when click it will popup a dialog box that user can edit that will binding from them.
the problem is, whenever user want to click the treeview user need to click on the listview first to get the SelectedItem. if not nothing will happen since the SelectedItem will be null.
this is the code behind for listview
private void LvItemDisplay_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListViewItem listViewItem = (ListViewItem)(LvItemDisplay.ItemContainerGenerator.ContainerFromItem(LvItemDisplay.SelectedItem));
TreeView treeView = null;
DialogHost dialogHost = null;
if (LvItemDisplay.SelectedIndex != -1)
{
if (listViewItem != null)
{
//get the listViewItem's template parent
ContentPresenter templateParent = GetFrameworkElementByName<ContentPresenter>(listViewItem);
//get the DataTemplate that treeview in.
DataTemplate dataTemplate = LvItemDisplay.ItemTemplate;
if (dataTemplate != null && templateParent != null)
{
treeView = dataTemplate.FindName("TvItemDisplay", templateParent) as TreeView;
if (treeView != null)
{
dialogHost = dataTemplate.FindName("dialogBoxEditQty", templateParent) as DialogHost;
dialogHost.IsOpen = true;
}
}
}
}
}
and for treeview
private void TvItemDisplay_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
ListViewItem listViewItem = (ListViewItem)(LvItemDisplay.ItemContainerGenerator.ContainerFromItem(LvItemDisplay.SelectedItem));
TreeView treeView = null;
DialogHost dialogHost = null;
if (listViewItem != null)
{
//get the listViewItem's template parent
ContentPresenter templateParent = GetFrameworkElementByName<ContentPresenter>(listViewItem);
//get the DataTemplate that treeview in.
DataTemplate dataTemplate = LvItemDisplay.ItemTemplate;
if (dataTemplate != null && templateParent != null)
{
treeView = dataTemplate.FindName("TvItemDisplay", templateParent) as TreeView;
}
if (treeView != null)
{
dialogHost = dataTemplate.FindName("dialogBoxEditQty", templateParent) as DialogHost;
dialogHost.IsOpen = true;
}
}
}
save for dialogHost
private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
try
{
// get the current selected item
ListViewItem listViewItem = (ListViewItem)(LvItemDisplay.ItemContainerGenerator.ContainerFromItem(LvItemDisplay.SelectedItem));
DialogHost dialogHost = null;
if (listViewItem != null)
{
.
.
.
I want something like whenever user click on the treeview it will triggered the listview behind /click the listview as well. is it possible ?
You can manualy select the ListView Item
TreeView Selection Changed
private void TvItemDisplay_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
LvItemDisplay.SelectionChanged -= LvItemDisplay_SelectionChanged;
ParentItemSelectionChange(sender, true);
// Your code
ParentItemSelectionChange(sender, false);
LvItemDisplay.SelectionChanged += LvItemDisplay_SelectionChanged;
}
Helper Methods
private FrameworkElement ParentItemSelectionChange(object sender, bool selChange)
{
var frameworkElement = sender as FrameworkElement;
if (frameworkElement != null)
{
var item = FindParent<ListViewItem>(frameworkElement);
if (item != null)
item.IsSelected = selChange;
}
return frameworkElement;
}
public T FindParent<T>(DependencyObject child) where T : DependencyObject
{
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
if (parentObject == null) return null;
T parent = parentObject as T;
if (parent != null)
return parent;
return FindParent<T>(parentObject);
}

Drag and drop selected item as list box return null

Im using the following code for drag and drop and the following statement
return null when I checked it in the debug,what is wrong here?
var mySelectedItem = listbox1.SelectedItem as ListBoxItem;
public MainWindow()
{
InitializeComponent();
_UsersList.Add(new User {Name = "Mike"});
_UsersList.Add(new User { Name = "Nick" });
listbox1.ItemsSource = _UsersList;
}
public ObservableCollection<User> userList
{
get { return _UsersList; }
}
private void listbox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0 && string.IsNullOrEmpty(textbox1.Text))
{
if (listbox1.SelectedItems.Count > 0)
{
var mySelectedItem = listbox1.SelectedItem as ListBoxItem;
if (mySelectedItem != null)
{
DragDrop.DoDragDrop(listbox1, DragDropEffects.Copy);
}
}
}
}
the xaml is
<ListBox x:Name="listbox1" HorizontalAlignment="Left" Height="115" Margin="100,75,0,0"
VerticalAlignment="Top" Width="150" ItemsSource="{Binding userList}"
SelectionChanged="listbox1_SelectionChanged" >
UPDATE:
When I change the lilstBOXItem to User or using the following as proposed in the answers im getting different error :
var mySelectedItem = listbox1.ItemContainerGenerator
.ContainerFromItem(listbox1.SelectedItem) as ListBoxItem;
private void textbox1_PreviewDrop(object sender, DragEventArgs e)
{
string name = e.Data.GetData(DataFormats.StringFormat).ToString();
textbox1.Text += name;
textbox1.Focus();
textbox1.CaretIndex = textbox1.Text.Length;
e.Handled = true;
listbox1.Items.Remove(listbox1.SelectedItem);
}
The error in listbox1.Items.Remove(listbox1.SelectedItem);
this statement responsible to remove item that was selected from the list box and dragged to the text box
peration is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead."}
SelectedItem will be of type User.
If you want to get container i.e. ListBoxItem you can get this way:
var mySelectedItem = listBox1.ItemContainerGenerator
.ContainerFromItem(listBox1.SelectedItem) as ListBoxItem;
This will get you actual container which is hosting your object of type User.
UPDATE
Instead of
listbox1.Items.Remove(listbox1.SelectedItem);
you should remove from ItemsSource collection and since its ObservableCollection<User>, it will update UI automatically.
_UsersList.Remove(listBox1.SelectedItem)
Try this
var mySelectedItem = listbox1.SelectedItem as User;
Your ItemsSource is a collection of Type User and thus The SelectedItem will be of Type User not of ListBoxItem

double tap on list view

When I double tap on a list view item I am getting the DoubleTapped event.
But I am not sure how to get the selected item on which the tap was performed.
ListView.Selecteditem does not give me the tapped item.
Please help.
DataGrid and ListView had nice method HitTest, by which you can get selected item.
private void ListView_Tapped(object sender, TappedRoutedEventArgs e)
{
var listView = sender as ListView;
if (!(sender is ListView))
{
return;
}
var hitTest = listView.HitTest(e.X, e.Y);
ListViewItem tappedListViewItem = hitTest.Item;
}
I have found a way to solve this.
When a listview item is tapped before getting the DoubleTap event , you will get GetFocus event.
In that event you will get the selected item and you can use this selected item in Doubletap.
private async void OnDoubleClick(object sender,
Windows.UI.Xaml.Input.DoubleTappedRoutedEventArgs e)
{
}
private void OnFocus(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
ListviewItem lv = (ListViewItem)e.OriginalSource;
string str = lv.SelectedItem.tostring();
}
Thanks
As Aaron Xue said here, you can't get the clicked item via Tapped event directly. However you can get the Y coordinate and calculate the item index we clicked then get the item:
private void ListView_Tapped(object sender, TappedRoutedEventArgs e)
{
int item = 0;
Double coY = e.GetPosition((UIElement)sender).Y;
ListView lv = sender as ListView;
if (sender is ListView)
{
lv.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
Size lvSize = lv.DesiredSize;
item = (int)(coY / lvSize.Height * lv.Items.Count);
item = item > lv.Items.Count ? lv.Items.Count : item;
}
var TappedItem = lv.Items[item];
}

Setting label text in listview control in loggedin template

I need to set a label text which is listview and the listview is in Logged in template.
I am unable to set the value of the label. Here is the below code.
ListView ListView1 = (ListView)LoginView.FindControl("ListView1");
for (int i = 0; i < ListView1.Controls.Count; i++)
{
Label someLabel = (Label)ListView1.Controls[i].FindControl("nItemsId");
if (someLabel != null)
someLabel.Text = dt.Rows.Count.ToString();
}
So I think you need to use ListView.ItemCreated Event to achieve this
protected void LV_ItemCreated(object sender, ListViewItemEventArgs e)
{
// Retrieve the current item.
ListViewItem item = e.Item;
// Verify if the item is a data item.
if (item.ItemType == ListViewItemType.DataItem)
{
Label someLabel = (Label)ListView1.Controls[i].FindControl("nItemsId");
if (someLabel != null)
someLabel.Text = dt.Rows.Count.ToString();
}
}
To use it change your markup to declared the eventHandler like this.
<asp:ListView OnItemCreated="LV_ItemCreated" />

How to select vertical ListView item based on its current position using XAML and C#?

I'm trying to do something tricky. I want to select a list item by determining whether the ScrollViewer is scrolled and if the item is in the center of the ScrollViewer. I want to select an item when the user manually scrolls it to the center of a ListView. I do not want to scroll to the selected item, because that would be too easy, right?
Here's a drawing:
I've managed to detect whether the scroller has been scrolled. First I place a Loaded Event on the ListView in question "itemsList" and find the ScrollViewer type by traversing the visual tree to see if it has finished scrolling and tag the ScrollViewer to the ListView and handle the SelectionChanged event:
private void ItemsList_OnLoaded(object sender, RoutedEventArgs e)
{
var listView = (sender as ListView);
if (listView != null)
{
var scrollers = FindVisualChildren<ScrollViewer>(sender as DependencyObject);
var scrollView = scrollers.First();
if (scrollView != null)
{
scrollView.Tag = listView;
scrollView.ViewChanged += ScrollViewOnViewChanged;
listView.SelectionChanged += listView_SelectionChanged;
}
}
}
public IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
I handle the ScrollViewOnViewChanged event where I determine if the scrollviewer is still scrolling. This is where I'm running into a few problems where I also need to determine the position of the ListViewItem and select it - I'd love some help here:
private void ScrollViewOnViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
//Debug.WriteLine("ScrollViewOnViewChanged + IsIntermediate="+e.IsIntermediate);
var scrollviewer = sender as ScrollViewer;
var listview = scrollviewer.Tag as ListView;
if (!e.IsIntermediate)
{
Debug.WriteLine("IsIntermediate = false");
// TODO: Determine the center Item and set is as the selected item for this group.
}
}
Then the SelectionChanged event where I make some magic happen:
void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Debug.WriteLine("SelectionChanged");
}
Thanks! Any help would be appreciated!
You can get the item in the middle by using the method InputHitTest of ScrollViewer.
Example:
IInputElement element = scrollViewer.InputHitTest(
new Point(scrollViewer.Width / 2, scrollViewer.Height / 2));

Categories