XAML Scroll intoView wont work in async function? - c#

im using the following code to display some tweets in a ListView.
I'm inserting every tweet at position index = 0 to display the latest tweet at the bottom of the listView (x:name = standardTweetBox).
private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{[...]
if (searchResponse != null && searchResponse.Statuses != null)
{
foreach (Status status in searchResponse.Statuses)
{
Tweet tweet = new Tweet(status.User.ScreenNameResponse, status.User.ProfileImageUrl, status.Text, status.CreatedAt.ToString());
standardTweetBox.Items.Insert(0, tweet);
}
}
Usually the following code should work to focus at the latest tweet at the bottom of the listView
standardTweetBox.ScrollIntoView(standardTweetBox.Items[standardTweetBox.Items.Count - 1]);
I was succesfull to implement this line of code at a different part of the code. Of course using the event TextBox_Change doesnt make any sense, but it proves to code to be working.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
standardTweetBox.ScrollIntoView(standardTweetBox.Items[standardTweetBox.Items.Count-1]);
}
Is it possible that this line of code just doenst work properly in an async function?
Here is my XAML code if needed:
<ListView Grid.Row="1"
x:Name = "standardTweetBox"
ItemTemplate="{StaticResource TweetBox}"
HorizontalAlignment="Center"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VerticalAlignment="Bottom"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
<!--</ScrollViewer>-->
<TextBox Grid.Row="2" Height="150" Width="380" Text="{Binding Title}" Background="#99FFFFFF" TextChanged="TextBox_TextChanged"/>
Let me know if you need any further information.
Cheers

Related

how to clear collectionview selection in xamarin

On Page#1, i have a collectionview with text/string items list. If you tap a a item, it will get the current tapped text/string and send to Page#2. sound simple
issue I am having: if you tap on item#1, then it will send item#1 to page2, this part working fine. But on page#2, if you hit back button, and tap on item#1 again.. than nothing happens, it doesnt go to page#2
Fix: i think i need to somehow clear tap selection, and than send the item to page#2. but im not sure how to do this
On Page#1, i have a simple collectionview. Collection view contains text/string list
<CollectionView ItemsSource="{Binding MyListItem}"
SelectionMode="Single"
SelectionChanged="CollectionView_SelectionChanged">
<CollectionView.ItemTemplate>
<DataTemplate>
<ContentView>
<!-- Body -->
<Grid Padding="0">
<Frame CornerRadius="3" BorderColor="#f2f4f5" HasShadow="True">
<StackLayout Orientation="Horizontal">
<Image Source="icon_about"
WidthRequest="25" />
<StackLayout VerticalOptions="Center">
<Label VerticalOptions="Center"
FontSize="16"
Text="{Binding .}" />
</StackLayout>
</StackLayout>
</Frame>
back end code to handle selection is:
private async void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var previous = e.PreviousSelection.FirstOrDefault();
var current = e.CurrentSelection.FirstOrDefault();
var route = $"{ nameof(Page2) }?URLCardType={current}";
await Shell.Current.GoToAsync(route);
//clear selection
((CollectionView)sender).SelectedItem = null;
}
Update ((CollectionView)sender).SelectedItem = null; fixed the issue of clearing selected item but CollectionView_SelectionChanged method is get run twice on single tap. why? this is all the code i have
#jason thanks, this worked for me. i just had to check if selection item is null than do nothing
private async void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var MyCollectionView = sender as CollectionView;
if (MyCollectionView.SelectedItem == null)
return;
var previous = e.PreviousSelection.FirstOrDefault();
var current = e.CurrentSelection.FirstOrDefault();
var route = $"{ nameof(Page2) }?URLCardType={current}";
await Shell.Current.GoToAsync(route);
//clear selection
MyCollectionView.SelectedItem = null;
}
Here is a simple solution that worked for me.
Setting to null did not do the trick, it was causing all kinds of
weird stuff.
private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var itemselected = e.CurrentSelection[0] as ProductsItem;
if (itemselected != null)
Shell.Current.GoToAsync(nameof(SelectedProductPage));
//Setting the selected item to an emptyviewproperty after navigation
CollectionList.SelectedItem = SelectableItemsView.EmptyViewProperty;
}

C# WPF Virtualizing ListView Issue

I have the following WPF and C# excerpt in a Visual Studio 2010 application. This code is being caught in the exception when I run my application and saying the content is "{DisconnectedItem}". To me that would mean that my 'loadDesc' function is being called for objects (Checkboxes) that are not currently inside view of the ListView. Why is this? Any help is appreciated.
C# and WPF Code Below:
private void loadDesc(object sender, RoutedEventArgs e)
{
try
{
string num = (string)(((sender as TextBlock).Parent as StackPanel).Children[0] as CheckBox).Content;
if (num == null)
{
return;
}
if (num.Equals("Tamper"))
{
(sender as TextBlock).Text = "";
}
else
{
int x = Convert.ToInt32(num);
dc.ext247[x - 1].desc = ZoneDescriptionsVM.getInstance().zoneDesc[x - 1].description.Trim();
dc.onOff247[x - 1].desc = ZoneDescriptionsVM.getInstance().zoneDesc[x - 1].description.Trim();
}
}
catch (Exception ex)
{
MessageBox.Show((((sender as TextBlock).Parent as StackPanel).Children[0] as CheckBox).Content.ToString());
}
}
<ListView KeyboardNavigation.TabNavigation="Continue" VirtualizingStackPanel.VirtualizationMode="Recycling" BorderThickness="0" Width="260" MaxHeight="400" Margin="10" Name="zonesOnOffStack" SelectionMode="Single">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Visibility="{Binding visible}" IsChecked="{Binding enabled}" Content="{Binding name}" />
<TextBlock Padding="5,-1,0,0" Loaded="loadDesc" Text="{Binding desc, StringFormat={}({0})}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
I see this is old, so maybe not that helpful, but I wanted to note a few things.
In VS2017 I setup something similar and was unable to reproduce, but I assume this is verbatim code you pasted
Mainly, DisconnectedItem seems to be the key, and that is a binding expression issue. I'm curious if the version of xaml you were using didn't like your stringformat not being in single quotes.
Proof that disconnected item is a binding thing:
https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Data/BindingExpressionBase.cs,71f3b982041c21ce
Hope that helps :)

Tap and hold Listbox Windows Phone

Does anybody know how can I add event whenever I press my listbox it will directly run my code. I need it to change my listbox selected item. This is my xaml:
<ListBox x:Name="ListNabi" SelectionChanged="ListNabi_SelectionChanged" ItemsSource="{Binding}" Tap="ListNabi_Tap" Hold="ListNabi_Hold">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="5,0,5,0">
<!--<Image Source="{Binding ImageSource}" Stretch="None"/>-->
<Grid Width="480" Background="White">
<Image x:Name="listDaun" Source="/Images/Button/Button List.png"
Margin="0,5,5,5" Width="38" HorizontalAlignment="Left"></Image>
<TextBlock x:Name="namaNabi" TextWrapping="NoWrap"
Text="{Binding Name}" FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="36" Foreground="#00ADCE" Margin="40,5,0,5"></TextBlock>
<Rectangle Margin="0,50,0,0" Height="2" Fill="#00ADCE" Width="480"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And in CS I did like this:
private void ListNabi_Hold(object sender, System.Windows.Input.GestureEventArgs e)
{
changeColor("#00ADCE", "#FFFFFF", "#FFFFFF", "/Images/Button/Button List1.png");
}
private void ListNabi_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
if (ListNabi.SelectedIndex != -1)
{
id = ListNabi.SelectedIndex;
}
MessageBox.Show("tes");
changeColor("#00ADCE", "#FFFFFF", "#FFFFFF", "/Images/Button/Button List1.png");
}
private void ListNabi_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ListNabi.SelectedIndex != -1)
{
id = ListNabi.SelectedIndex;
changeColor("#00ADCE", "#FFFFFF", "#FFFFFF", "/Images/Button/Button List1.png");
NavigationService.Navigate(new Uri("/Pages/25_Nabi/DetailPage.xaml?id="
+ ListNabi.SelectedIndex, UriKind.Relative));
ListNabi.SelectedIndex = -1;
}
}
But it will only run my code (in this context changeColor()) whenever I hold my listbox after some time or after I release my finger. Is there any event I can use to start run my code whenever my finger start touch?
For that use the following events: ManipulationStarted, ManipulationDelta and ManipulationCompleted. You will get everything you need from positions to the number of different touch points.
You can do sophisticated things with it like dragging and pinching.

How to select an item from a listbox in windows phone?

I've a list of data,
Each row will show a data and will have a button, when i click the data shown i want give some data to the previous page and when i click the button in the same row i want to send that same data to next page.
My Xaml code,
<ListBox x:Name="List" HorizontalAlignment="Left" Height="612" Margin="6,7,0,0" VerticalAlignment="Top" Width="443" SelectionChanged="List_SelectionChanged_1">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Width="420" Height="50">
<TextBlock x:Name="tbName" Width="400" Height="44" FontSize="22" FontWeight="Bold" Text="{Binding Name}" />
<Button x:Name="DetailButton" Height="44" Width="20" Content=">" FontWeight="Bold" Click="DetailButton_Click_1"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and the code for List_SelectionChanged_1 event handler is,
private void List_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
Display selectedItemData = (sender as ListBox).SelectedValue as Display;
NavigationService.Navigate("/Page1.xaml",selectedItemData);
}
and my DetailButton_Click_1 event handler is,
private void DetailButton_Click_1(object sender, RoutedEventArgs e)
{
Display selectedItemData = (sender as ListBox).SelectedValue as Display;
NavigationService.Navigate("/page3.xaml", selectedItemData);
}
Things work fine for *List_SelectionChanged_1*, but i get an exception while executing
Display selectedItemData = (sender as ListBox).SelectedValue as Display;
of the DetailButton_Click_1 , i get an exception a null exception,
An exception of type 'System.NullReferenceException' occurred in ExpenseApp.DLL but was not handled in user code
What should i do make it work?
The underlying problem is that the sender of the button click event is the button, not the ListBox.
Also note that clicking the button on your data template will not necessarily select that item in the list. Try to grab the clicked item's data context and use that instead of .SelectedItem
private void DetailButton_Click_1(object sender, RoutedEventArgs e)
{
var clickedUIElement = sender as Button;
if (null == clickedUIElement) { Return; }
Display selectedItemData = clickedUIElement.DataContext as Display;
if(null != selectedItemData)
{
NavigationService.Navigate("/page3.xaml", selectedItemData);
}
}
Your code, as it stands, will have a null reference since you can't cast a Button as a ListBox.
try verify if the selectvalue is null before execute the code:
private void DetailButton_Click_1(object sender, RoutedEventArgs e)
{
If ((sender as ListBox).SelectedValue != null){
Display selectedItemData = (sender as ListBox).SelectedValue as Display;
NavigationService.Navigate("/page3.xaml", selectedItemData);
}
}

How to extract value from selected TextBlock element in a ListBox?

I'm using a ListBox to display all values contained in Dictionary<> object:
<ListBox Height="519" x:Name="ContactsListBox" Width="460" Margin="0,0,0,0" SelectionChanged="ContactsListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Key}" Margin="5" Foreground="{StaticResource PhoneAccentBrush}"/>
<TextBlock x:Name ="LastNameData" Text="{Binding Value}" Margin="20, 0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Content is filled by the following code:
Dictionary<long, Contact> contacts = new Dictionary<long, Contact>();
this.ContactsListBox.ItemsSource = contacts;
Now, I would like to 'know' which specific "Contact" in ListBox is currently selected, either by knowing its Key, or just by extracting value from "LastNameData" TextBlock.
I tried doing something like that, but obviosly it doesn't work:
private void ContactsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox lb = this.ContactsListBox.SelectedItem as ListBox;
this.Test_SomeOtherTextBlock.Text = lb.ToString();
}
I would really appreciate your help!
you can even do the follwing:
<ListBox Height="519" x:Name="ContactsListBox" Width="460" Margin="0,0,0,0" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Key}" Margin="5"/>
<TextBlock x:Name ="LastNameData" Text="{Binding Value}" Margin="20, 0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid DataContext="{Binding ElementName=ContactsListBox, Path=SelectedItem}" Margin="0,470,0,0">
<TextBlock Text="{Binding Value}"/>
</Grid>
So you don't need code behind...
BR,
TJ
There are several problems:
In Xaml you probably don't want to display the class name, but a reasonable string, for example:
<TextBlock x:Name ="LastNameData" Text="{Binding Value.LastName}" Margin="20, 0" />
In the selection processing the selected item is KeyValuePair<...>. You could easily find it yourself, if you looked at the returned type in debugger. (Should be kind of a reflex for a programmer, hence a questions like above should never appear :))
private void ContactsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
KeyValuePair<long, Contact> kv = (KeyValuePair<long, Contact>)this.ContactsListBox.SelectedItem;
Contact c = (Contact)kv.Value;
Debug.WriteLine(c.LastName);
}
Your code is good, using ListBox.SelectedItem is the right approach.
I think the problem is that you should cast it as ListBoxItem, not ListBox. And also to get to its value using DataContext, so something like along these lines (not tested, I'm not sure about accessing DataContext value in the last line):
private void ContactsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBoxItem lbi = this.ContactsListBox.SelectedItem as ListBoxItem;
var dataContext = lbi.DataContext;
this.Test_SomeOtherTextBlock.Text = dataContext.Value.ToString();
}
Try this it works for me, will help you to...
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox ContactListBox = sender as ListBox;
ListBoxItem listBoxItem = ContactListBox .ItemContainerGenerator.ContainerFromItem(ContactListBox.SelectedItem) as ListBoxItem;
if (listBoxItem == null)
{
return;
}
TextBlock txtBlock = FindVisualChildByName(listBoxItem, "ListTextBlock");
MessageBox.Show(txtBlock.Text);
}
private static T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
string controlName = child.GetValue(NameProperty) as string;
if (controlName == name)
{
return child as T;
}
T result = FindVisualChildByName<T>(child, name);
if (result != null)
return result;
}
return null;
}
private void ContactsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox lb = this.ContactsListBox.SelectedItem as ListBox;
this.Test_SomeOtherTextBlock.Text = lb.ToString();
}
will go something like this..
private void ContactsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox lb = this.ContactsListBox.SelectedItem as ListBox;
DataTemplate template=lb.ContentTemplate;
//Now here you have to extract the content of the data template
and then you need to extract the TextBlock from that content.
}
This is just an overview of the functionality.Sorry not able to post complete code.

Categories

Resources