How to automatically call Event in Windows Phone 8 - events

How to automatically raise event in windows phone? For example, I have an element <Image name = "image" .... />. I want when a MainPage is loaded, it will automatically raise tap event on that element

If you want to declare tap event dynamically (loads tap event on page load), You can declare it in following way. Here is your xaml.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Image Name="image1"/>
</Grid>
And in constructor,
public MainPage()
{
InitializeComponent();
image1.Tap += image1_Tap;
}
void image1_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
//Perform your action here
//This method invokes only when you tap on image
}
Else, try the other way.
Loaded += (s, e) =>
{
//Actions that are performed when image is tapped
}
Add above lines in your constructor.

This probably is not a good solution to whatever you are trying to accomplish. It can be done with reflection - How to manually invoke an event? However I'd just extract your Tap event code to method and then call this method in your Loaded event and also Tap even.

Related

.net maui CarouselView is not quite compatible with Slider control: CarouselView swipe operation takes over Slider's drag action

.net maui app.
Dragging value element along the slider bar does not work if the the slider put into CarouselView's template like this:
<CarouselView ItemsSource="{Binding Items}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Slider Minimum="0" Maximum="30" WidthRequest="200" />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
CarouselView takes over the swipe event for scrolling through the items, and Slider does not get the event (DragStarted is not even called). You can actually click along the slider bar to change its value, so it's not completely frozen, but not how it's supposed to work. Drag & drop is main way user deal with slider control.
Could anyone advise any workaround? I want users to be able scroll through carousel view items also. It's just if they swipe inside the control, event should not handed over to its parent container, if it's possible to do so.
If I add it outside of the corouselview, combine both in Grid and use padding to align slider inside the corouselview, it works as expected, but I need to add lots of additional code, calculate the desirable location and redirect all bindings, which ends up to be an awkward workaround.
At first, I don't suggest you use the slider in the CarouselView. Becasue you want the same behavior has two effects. There is a conflict between them.
But for the android, you can use the custom handler to deal with the swipe event.
Put the Handler class in the /Platform/Android:
public class MySliderHander : SliderHandler
{
protected override void ConnectHandler(SeekBar platformView)
{
base.ConnectHandler(platformView);
platformView.SetOnTouchListener(new SliderListener());
// the listener will make the slider deal with the swip event not the CarouselView.
}
}
Put the SliderListener class in the /Platform/Android
public class SliderListener : Java.Lang.Object, IOnTouchListener
{
public bool OnTouch(global::Android.Views.View v, MotionEvent e)
{
if (e.Action == MotionEventActions.Down || e.Action == MotionEventActions.Move)
{
v.Parent.RequestDisallowInterceptTouchEvent(true);
}
else
{
v.Parent.RequestDisallowInterceptTouchEvent(false);
}
return false;
}
}
And in the MauiProgram.cs:
builder
                  .UseMauiApp<App>()      
                  .ConfigureMauiHandlers(handlers => {
#if ANDROID
                        handlers.AddHandler(typeof(Slider), typeof(YourProjectName.Platforms.Android.MySliderHander));
                  #endif
                  })
In addition, the Slider's height is same as the CarouselView. So you can use a frame to contain the Slider and swipe the CarouselView by swiping the frame.

Xamarin XAML variable scope not working like expected

I have a really odd problem with variable scopes. A Listview named "TodoListView" is defined via xaml, and it's ItemSource populated from a SQListe database. Works. Inside the ListView I have a ViewCell to display the data row-wise.
<ContentPage ... x:Class="JanitorPro.MainPage" ...>
<StackLayout>
<ListView x:Name="TodoListView" Margin="20" ItemSelected="OnListItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<Label Text="{Binding name}" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand" />
<Switch HorizontalOptions="End" IsToggled="{Binding done}" Toggled="DoneSwitchToggled"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
The codebehind looks like this (some irrelevant portions removed):
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
protected override async void OnAppearing()
{
base.OnAppearing();
// load Database
TodoListView.ItemsSource = await App.TodoDatabase.GetItemsAsync("SELECT * FROM [TodoItem]");
}
async void OnReloadButtonClicked(object sender, EventArgs e)
{
Debug.WriteLine("Reload Button Click");
TodoListView.ItemsSource = await App.TodoDatabase.GetItemsAsync("SELECT * FROM [TodoItem]");
Debug.WriteLine("Reload done.");
}
async void OnListItemSelected(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem != null)
{
await Navigation.PushAsync(new TodoItemPage
{
BindingContext = e.SelectedItem as TodoItem
});
}
}
private void DoneSwitchToggled(object sender, ToggledEventArgs e)
{
// TodoItem i = null;
TodoItem i = TodoListView.SelectedItem;
if (i != null)
{
Debug.WriteLine("Toggle: {0}", i.id);
}
}
}
}
The oddity has two stages. Before I inserted the DoneSwitchToggled event handler, every occurrance of TodoListView.ItemsSource got a red underline under TodoListView and a hint that "The name TodoListView does not exist in the current context". OK, I thought that VS was not smart enough to find a definition in the xaml file, because, despite of the warning, the program compiled and ran fine. TodoListView gets initialized and does correctly display the rows of the underlying database, so it does clearly exist at runtime.
Things went wild when I added the DoneSwitchToggled event handler to both XAML and the codebehind. All the sudden the program won't compile any longer but bail out with a CS0103 error "The name "TodoListView" does not exist in the current context". The error appears three times, with the line numbers pointing to the other occurrances of TodoListView in onAppearing() and OnReloadButtonClicked(). Huh? How the heck can the addition of a variable reference in an event handler render that variable invalid in completely different methods? OK, there was something fishy with the variable before (still don't know what ...), but it worked. Now it doesn't any more, whch doesn't make any sense for me. Furthermore, if I comment out the offending line in the DoneSwitchToggled event handler, and insert a dummy definition for i, like so:
TodoItem i = null;
// TodoItem i = TodoListView.SelectedItem;
everything is like before, VS still underlines the other appearances of TodoListView, but now the program builds and runs ok again.
Anyone who can explain this effect, and show me how correct my code? I think the objective is clear: DoneSwitchToggled is supposed to write back the switch value into the database (and do some other processing not shown in my stripped down sample), and though the "sender" object is correctly set to reference my button, I found no way to access the underlying data binding, since ToggledEventArgs unfortunately does seem to only pass the switch position "true" or "false", but - unlike the OnListItemSelected event handler - not pass any reference to the bound row through the second argument. So my idea was to use ListView.SelectedItem for this purpose.
Finally I figured it out myself. This seems to be a glitch in VS 2017. There is nothing wrong with TodoListView, so error CS0103 is misleading nonsense.
What VS really means is an error CS0266. TodoListView is defined by a generic list
List<TodoItem>
to access SelectedItem i need to typecast it:
TodoItem i = (TodoItem)TodoListView.SelectedItem;
This added, all errors are gone, app code builds OK.
Btw, unfortunately this approach to get at the item where the Switch has been flipped has proven not working, TodoListView does always return null for SelectedItem, seems that the ListView control doesn't see the button press. Need to find a different way to find the list item beneath the switch to get at the bound row id.

When using a text cell, is it possible to get the value of the text when it is tapped?

The text cell is inside of a listview. I'm populating the text of the text cell with data using Binding. I need to actually get the value of the text when the text cell is clicked on. Is there a way to do this?
XAML file:
<ListView ItemsSource="{Binding MyItems}" ItemTapped="{Binding OnItemTapped}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Key}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListVIew>
You bind the ItemTapped event to a custom event handler using Binding.
In codebehind, e.Item will contain the tapped item, from which you can extract the Key and Value.
Codebehind:
public class MyPage : ContentPage
{
...
private async void OnItemTapped(object sender, ItemTappedEventArgs e)
{
var tappedItem = e.Item;
// do something with tappedItem.Value...
}
}
Edit/Note: You will need to override the ToString() method in your model class in order to display whatever you want. You get the namespace displayed because that's the default behavior of calling ToString() on any object.
You could subscribe to ItemTapped or ItemSelected ListView events and pull your item from ItemTappedEventArgs.Item (in case of ItemTapped event) or SelectedItemChangedEventArgs.SelectedItem (in case of ItemSelected event) . More info in official Xamarin documentation
If you using MVVM approach look at EventToCommandBehavior and Converter.
Xamarin have good example here

using TabControl in windows phone

I read the article about using a TabControl on Windows Phone application. I can avoid it to fire when it is first load. However, the selectionChanged fired twice when user click the tab. Would someone can help me how to fix it. Thanks in advance.
There is my TabControl:
<cc:TabControl Grid.Row="1" SelectionChanged="tabList_SelectionChanged" x:Name="tabList">
<cc:TabItem Height="80" Header="Events" Foreground="Black"/>
<cc:TabItem Height="80" Header="Details" Foreground="Black"/>
<cc:TabItem Height="80" Header="Notes" Foreground="Black" />
</cc:TabControl>
There is cobe behind:
public partial class Tab : PhoneApplicationPage
{
private bool blnFristLoad=true;
public Tab()
{
InitializeComponent();
tabList.SelectionChanged += new SelectionChangedEventHandler(tabList_SelectionChanged);
}
private void tabList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (blnFristLoad == false)
{
TabItem t = (sender as TabControl).SelectedItem as TabItem;
t.Content = "202020";
}
else blnFristLoad = false;
}
It's very obvious in your code. You are adding SelectionChanged event handler twice. One from your XAML code and the other from the code behind. As you are using += symbol, the eventhandler is added as a seperate instance.
Remove one of those statements.
Please use the Pivot control instead of a TabControl for the WindowsPhone. the Pivot control follows the design guidelines for the phone and looks and feels much better.

Get scroll event for ScrollViewer on Windows Phone

Question:
Get scroll event for ScrollViewer on Windows Phone
I have a scrollviewer like so:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ScrollViewer x:Name="MyScroller">
<StackPanel>
<!-- ... -->
</StackPanel>
</ScrollViewer>
</Grid>
I need the event for when the scrolling occurs for MyScroller:
// MyScroller.Scroll += // <-- "Scroll" event does not exist on ScrollViewer
MyScroller.MouseWheel += MyScroller_MouseWheel; // Does not fire on scroll
MyScroller.ManipulationDelta += MyScroller_ManipulationDelta; // Fires for pinch-zoom only
MouseMove fires when ScrollViewer is scrolled:
public MainPage()
{
InitializeComponent();
MyScroller.MouseMove += MyScroller_MouseMove;
}
void MyScroller_MouseMove(object sender, MouseEventArgs e)
{
throw new NotImplementedException();// This will fire
}
It isn't intuitive, since it is named as a "mouse" event and there is no mouse on the phone. The touch point does move, however, relative to the ScrollViewer container, which is how it can handle scrolling.
It's not that simple, but there's a few scroll detection mechanisms written in this question:
WP7 Auto Grow ListBox upon reaching the last item
Basically take a look at the way OnListVerticalOffsetChanged is called and used.
With Mango, you can watch for the "ScrollStates" visual state to change as described in this sample project.

Resources