I have a ListView in my xaml which is binded to ReadOnlyObservableCollection which contains items.
How can I scroll to the bottom of the ListView when all the binded list loaded?
I've tried to use the myList.ScrollToBottom() function as I add the data to mylist (on ViewModel) - the scroll isn't visible, it doesn't scroll till the end of the list.
I've tried to subscribe to Lists Loaded , CollectionChanged and ItemContainerGenerator.ItemsChanged events, and then to scroll to the bottom didn't helped either.
If I subscribe to my event (on ViewModel) which I fire as I set the data to my List, and then I call ScrollToBottom function with a slight delay - the scroll is perfect, so I guess it's timing issue...
Any help will be appreciated.
Try to use this:
myList.ScrollIntoView(myList.Items[myList.Items.Count - 1])
How are you doing this if you have a ViewModel? The ViewModel wouldn't know what control you're talking about. So how can your ViewModel reference "myList"?
I'm also trying to get the ListView to scroll to the last item when the collection is updated, but none of the ScrollTo features are available in in the XAML: THere's no way to bind to them. These seem to all be METHODS, meaning you can't do property MVVM with it.
Or am I missing something?
Related
I'm trying to make a search application using a wpf and entity framework following mvvm design patterns. When you search for someone, I want the ListBox to dynamically hold as many datagrids, as the search shows up. The datagrid will hold information such as first and last name, as well as a profile picture. I am kind of new to wpfs and c# in general, but I was thinking that the datagrid with all its information would be its own xaml. Then somehow I could add that xaml to the listbox as many times as I needed to(depending on the number of search results). Any help would be much appreciated.
Easy one: ListBox.ItemTemplate. The DataGrid XAML goes in the item template.
The search results go in an ObservableCollection of your search result class. That collection will be a member of your viewmodel, and in XAML you'll bind the collection to ListBox.ItemsSource.
The ListBox will instantiate the ItemTemplate once for each item in the search results collection.
Don't forget to implement INotifyPropertyChanged on your viewmodel, and raise PropertyChanged when you replace the collection with a new one. Changes to the collection's contents aren't your problem: use an ObservableCollection and it'll raise its own notifications for adds and removes. The ListBox will subscribe to those notifications without being asked.
I have a Windows 8.1 application with a GridView bound to a custom (sortable, deduplicated) observable collection. In this collection, I do some heavy filtering and setting an IsHidden flag for every item.
In the data template for the item, there is a condition making the item collapsed if IsHidden flag is set to true.
<Grid Width="160" Height="280" Visibility="{Binding IsHidden, Converter={StaticResource InvertedBooleanToVisibilityConverter}}">
This approach works in Windows Phone 8.1 XAML, making the items disappear from the ListView but it does not work in Windows 8.1 GridView. The problem with Windows 8.1 is that when I set an item in the collection to hidden, id disappears from the GridView but leaves an empty place, so there is a gap in the GridView.
Any ideas on how to solve it? Maybe same XAML style editing?
Here is a minimal solution to reproduce the problem: https://dl.dropboxusercontent.com/u/73642/gv.zip
I tried binding width and height of the items to the hidden flag and setting it to 0 when the item is hidden, but it did not help, still a gap in the GridView.
Update: One workaround would be filtering the actual bound collection, but this is not possible, because of some business requirements.
The problem is in the GridView's ItemsPanel.
Both ItemsWrapGrid and WrapGrid are uniform grids. All their child elements will be sharing the same height and width. That's why even if you collapse the ItemTemplate, the space is still reserved.
What you really need here is a WrapPanel. WINRT doesn't have a built-in WrapPanel but Jerry Nixon has built one and you can grab it from here.
After you updated your GridViews ItemsPanel, you still have one more thing to do. You need to also get the GridViewItem that hosts your Itemtemplate and set its Visibility to Collapsed.
private async void Button_Click(object sender, RoutedEventArgs e)
{
ds[5].IsHidden = true;
await Task.Delay(1000);
var gridViewItem =(GridViewItem)this.gv.ContainerFromIndex(5);
gridViewItem.Visibility = Visibility.Collapsed;
}
I put a little delay above to make the collapsing more obvious.
I tried your sample solution and changed it to a ListView instead. It exhibits the same behavior when the grid itself is hidden. I don't have XAML Spy to verify, but it appears that any List based control will allocate a rendered item for each item in the list.
I changed your click handlder to instead ds.RemoveAt(5); instead of hiding the item, and the element is removed from view with a nice animation. This appears to be as expected, and an interesting find.
It takes me a lot of time to understand the problem, and the solution right in front of my eyes. You trying to hide the item itself but the container still there, When you add an item to an GridView, the item is wrapped in an item container. from msdn :
" When you add an item to an ItemsControl, the item is wrapped in an
item container. For example, an item added to a ListView is wrapped in
a ListViewItem. Without UI virtualization, the entire data set is kept
in memory and an item container is also created for each item in the
data set. A ListView that's bound to a collection of 1000 items will
also create 1000 ListViewItem containers that are stored in memory."
You need to disable the container and create two DataTemplate and using DataTemplateSelector you can choose which DataTemplate for disable and active items. Check this useful article .
I have an ItemsControl control which is data-bound to a list. In the ItemsControl is a DataTemplate which displays all data-bound items as buttons.
Now I want the first button to receive focus.
When do set the focus? Doing this in the ContentRendered and DataContextChanged events don't work the controls don't seem to be rendered at that point.
Bonus question: what's the best way to look up such a button on my window?
I'm guessing the DataContextChanged event doesn't work because the DataContext actually changes before the ObservableCollection you are binding to has any content.
I haven't had a chance to test it, but just a thought, perhaps you could try setting the focus in the TargetUpdated event handler on your binding to your ItemsSource.
The only issue with this is that if the collection continues to update then the focus will continually return to the first button, but this is something you can handle with a simple flag.
So I'm getting a weird behavior with the native LongListSelector from WP8.
It's ItemSource is bound to an
ObservableCollection<Group<Something>>
Everything is displayed correctly, but when the list appears on screen, I'm at the bottom of the list instead of it's top.
The only thing I do is to fill the ObservableCollection via it's Add() Method.
Is this a known behavior or is there a workaround ?
It is a normal behaviour as you are adding items one-by-one. for required behaviour kindly feed the list and then set it to observable collection
I have a ListView which I am constantly adding items in.
I am able to scroll while the items in the ListView were being added.
However, upon selecting an item in the ListView, I am unable to scroll while items are being added. For each ListView.Items.Add(Object) I call, I will revert to the focus of the item initially selected.
Clearing the SelectedItems and SelectedIndices, I am still able to continue scrolling down the ListView as I keep popping back to the originally selected item anytime an item is added.
Could anyone advise how to get past this problem?
Thank you.
Regards,
Michael
If you're using WPF, are you using an ObservableCollection? It sounds like the DataContext is being changed causing the ListView to reload. If you bind to an ObservableCollection you may have more luck.