I've been upgrading an MVVMCross project to v5.6.3
Mostly there, but I have a question. I've read and digesting this SO answer.
In my old code, which inherited from the MvxCachingFragmentCompatActivity class, I had the following method overload:
public override void OnBeforeFragmentChanging(IMvxCachedFragmentInfo fragmentInfo, Android.Support.V4.App.FragmentTransaction transaction)
{
var currentFrag = SupportFragmentManager.FindFragmentById(Resource.Id.content_frame) as MvxFragment;
if (currentFrag != null && fragmentInfo.ViewModelType != typeof(MenuViewModel)
&& currentFrag.FindAssociatedViewModelType(typeof(MainViewModel)) != fragmentInfo.ViewModelType)
fragmentInfo.AddToBackStack = true;
base.OnBeforeFragmentChanging(fragmentInfo, transaction);
}
Is this responsibility of adding a fragment to the backstack now handled by MVVMCross? Or is there a replacement method which I am meant to overload?
My observation is that the fragments are being added to the backstack, as evidenced by the previous fragment loading when I tap the back button.
Just wanted clarification on that if possible.
Cheers
i'm a beginner in learning actionscript and i'm seeing examples to learn from them. in the following lines, what should i add or remove so i can hide or not show system messages? and what are these lines actually say?
public function set showSystemMsgs(param1:Boolean) : void
{
var _loc:* = this.showSystemMsgs;
if (_loc !== param1)
{
this.showSystemMsgs = param1;
this.dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "showSystemMsgs", _loc, param1));
}
return;
}
public function get showSystemMsgs() : Boolean
{
return this.showSystemMsgs;
}
public function removeEventListener(param1:String, param2:Function, param3:Boolean = false) : void
{
_bindingEventDispatcher.removeEventListener(param1, param2, param3);
return;
}
If your goal is to understand code, stop reading decompiled code. This is not code meant to be read by humans opposed to what the code looked like before compilation.
There are plenty of resources on pretty much everything available by now, with explanations, comments and readable code.
object.showSystemMsgs = false;
Might work, where object is a reference to an object of the class which you partially posted.
I've got a WP8 project that is using the MonoGame framework. I have some code that should recognize Horizontal and Vertical drag events and perform an action but I never seem to get these events. I do get a FreeDrag gesture but the Deltas are always NaN.
I initialize the TouchPanel.EnabledGestures in the Initialize method of the game as follows:
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
TouchPanel.EnabledGestures = GestureType.HorizontalDrag | GestureType.FreeDrag;
}
I have a method that checks the gesture type as follows:
private void CheckUserGesture()
{
while (TouchPanel.IsGestureAvailable)
{
var gesture = TouchPanel.ReadGesture();
switch(gesture.GestureType)
{
case GestureType.DragComplete:
System.Diagnostics.Debug.WriteLine("Drag Complete");
break;
case GestureType.FreeDrag:
System.Diagnostics.Debug.WriteLine("Drag Complete");
break;
case GestureType.HorizontalDrag:
if (gesture.Delta.X < 0)
gameVm.MoveLeft(Math.Abs((int)gesture.Delta.X));
if (gesture.Delta.X > 0)
gameVm.MoveRight((int)gesture.Delta.X);
break;
case GestureType.VerticalDrag:
if (gesture.Delta.Y > 0)
gameVm.MoveDown(Math.Abs((int)gesture.Delta.Y));
break;
case GestureType.Tap:
System.Diagnostics.Debug.WriteLine("Rotating Shape Due To Tap Command");
gameVm.RotateClockwise();
break;
}
}
}
And this is called in the Update method:
protected override void Update(GameTime gameTime)
{
base.Update(gameTime);
// TODO: Add your update logic here
//CheckTouchGesture();
CheckUserGesture();
gameVm.UpdateGame((int)gameTime.ElapsedGameTime.TotalMilliseconds);
}
I've also tried using TouchState:
private void CheckTouchGesture()
{
var touchCol = TouchPanel.GetState();
foreach (var touch in touchCol)
{
// You're looking for when they finish a drag, so only check
// released touches.
if (touch.State != TouchLocationState.Released)
continue;
TouchLocation prevLoc;
// Sometimes TryGetPreviousLocation can fail. Bail out early if this happened
// or if the last state didn't move
if (!touch.TryGetPreviousLocation(out prevLoc) || prevLoc.State != TouchLocationState.Moved)
continue;
// get your delta
var delta = touch.Position - prevLoc.Position;
// Usually you don't want to do something if the user drags 1 pixel.
if (delta.LengthSquared() < DragTolerence)
continue;
if (delta.X < 0)
gameVm.MoveLeft(Math.Abs((int)delta.X));
else if (delta.X > 0)
gameVm.MoveRight((int)delta.X);
else if (delta.Y > 0)
gameVm.MoveDown((int)delta.Y);
}
}
But again the deltas are always NaN.
Is there something I'm missing that I might need to initialize?
I've tried various combinations of the EnabledGestures types but still can't get the dragging events to work. Flick doesn't work either.
Things like Tap are fine though.
Thanks
I think this is broken on the current release of MonoGame ( Version 3.0.1, Release date: Mar 3 2013 ).
Building the latest from the GitHub developer branch:
https://github.com/mono/MonoGame.git
(NOTE: I also built SharpDX too from here: https://github.com/sharpdx/SharpDX)
Seems to fix a lot of my problems
I'm not 100% convinced it is fully working though.
Using the touch.TryGetPreviousLocation() as shown in the code above always returns the same position as the current position so doing var delta = loc.Position - preLoc.Postion always results in 0.
At least I'm receiving the drag gestures now.
I'm trying to do something that's arguably a bad idea, but I think it's still possible. I'm trying to override how WP8 handles the Back Button and implement it myself. I theorize that if I:
The Plan
Only ever create one "Frame" and "Page" in the entire application
Always handle PhoneApplicationPage.BackKeyPress myself unless they were about to back out of the application.
The Repro
Here's a sample project that has the crash
The code
..then it should work. However, my attempts are being thwarted by Windows Phone. Here's the code:
// This basically happens on PhoneApplicationService.OnLaunched
_viewModelChanged.StartWith(ViewModel).Where(x => x != null).Subscribe(vm => {
var page = default(IViewFor);
var frame = RootVisual as PhoneApplicationFrame;
// Find the initial PhoneApplicationPage for the app
page = RxApp.GetService<IViewFor>("InitialPage");
// Depending on how we're being signalled (i.e. if this is cold start
// vs. resume), we need to create the PhoneApplicationFrame ourselves
if (frame == null) {
frame = new PhoneApplicationFrame() {
Content = page,
};
}
page.ViewModel = vm;
var pg = page as PhoneApplicationPage;
if (pg != null) {
pg.BackKeyPress += (o, e) => {
if (ViewModel.Router.NavigationStack.Count <= 1 ||
ViewModel.Router.NavigateBack.CanExecute(null)) {
return;
}
e.Cancel = true;
ViewModel.Router.NavigateBack.Execute(null);
};
}
// Finally, set Application.RootVisual
RootVisual = frame;
});
Sadness
This works great, until right after this code executes, where a DispatcherItem queued by the framework crashes the app:
System.NullReferenceException occurred
Message: A first chance exception of type 'System.NullReferenceException' occurred in Microsoft.Phone.ni.dll
Microsoft.Phone.ni.dll!Microsoft.Phone.Controls.PhoneApplicationPage.InternalOnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e) Unknown
Microsoft.Phone.ni.dll!Microsoft.Phone.Controls.PhoneApplicationPage.Microsoft.Phone.Controls.IPhoneApplicationPage.InternalOnNavigatedFromX(System.Windows.Navigation.NavigationEventArgs e) Unknown
Microsoft.Phone.ni.dll!System.Windows.Navigation.NavigationService.RaiseNavigated(object content, System.Uri uri, System.Windows.Navigation.NavigationMode mode, bool isNavigationInitiator, Microsoft.Phone.Controls.IPhoneApplicationPage existingContentPage, Microsoft.Phone.Controls.IPhoneApplicationPage newContentPage) Unknown
Microsoft.Phone.ni.dll!System.Windows.Navigation.NavigationService.CompleteNavigation(System.Windows.DependencyObject content, System.Windows.Navigation.NavigationMode mode) Unknown
Microsoft.Phone.ni.dll!System.Windows.Navigation.NavigationService.ContentLoader_BeginLoad_Callback(System.IAsyncResult result) Unknown
Microsoft.Phone.ni.dll!System.Windows.Navigation.PageResourceContentLoader.BeginLoad_OnUIThread(System.AsyncCallback userCallback, System.Windows.Navigation.PageResourceContentLoader.PageResourceContentLoaderAsyncResult result) Unknown
Microsoft.Phone.ni.dll!System.Windows.Navigation.PageResourceContentLoader.BeginLoad.AnonymousMethod__0(object args) Unknown
[Native to Managed Transition]
mscorlib.ni.dll!System.Delegate.DynamicInvokeImpl(object[] args) Unknown
System.Windows.ni.dll!System.Windows.Threading.DispatcherOperation.Invoke() Unknown
System.Windows.ni.dll!System.Windows.Threading.Dispatcher.Dispatch(System.Windows.Threading.DispatcherPriority priority) Unknown
System.Windows.ni.dll!System.Windows.Threading.Dispatcher.OnInvoke(object context) Unknown
System.Windows.ni.dll!System.Windows.Hosting.CallbackCookie.Invoke(object[] args) Unknown
System.Windows.RuntimeHost.ni.dll!System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(System.IntPtr pHandle, int nParamCount, System.Windows.Hosting.NativeMethods.ScriptParam* pParams, System.Windows.Hosting.NativeMethods.ScriptParam* pResult) Unknown
So, I've solved this - my code was problematic because I didn't grok how WP8 works :) Here's what I understand now, which may also be wrong but I'll write it anyways
How your WP8 app is initialized:
The OS creates your App class via rehydrating App.xaml.cs
This means, your constructor gets run, and as part of that, you create a PhoneApplicationFrame
Creating a PhoneApplicationFrame seems to also set a global static variable (same thing happens with creating PhoneApplicationService in the App.xaml, it sets PhoneApplicationService.Current).
NavigationService then attempts to recreate a XAML View via a resource string (i.e. '/MainPage.xaml'). Either it will recreate the one that was previously tombstoned, or if not, it defaults to the one in your WMAppManifest (this is the part I didn't understand).
PhoneApplicationFrame.Navigated gets called by NavigationService - this is where you can actually start doing stuff, including most importantly, setting Application.RootVisual, which will send the Loading... screen away
PhoneApplicationService.Launched or PhoneApplicationService.Activated finally fires, once basically everything is set up, depending how your app was woken up.
Found the issue. Well, the tip of the iceberg.
The code of the InternalOnNavigatedFrom method is:
internal override void InternalOnNavigatedFrom(NavigationEventArgs e)
{
PhoneApplicationPage content = e.Content as PhoneApplicationPage;
string str = ((content == null) || (content.Title == null)) ? string.Empty : content.Title;
PerfUtil.BeginLogMarker(MarkerEvents.TH_ONNAVIGATEDFROM_PAGE, string.Format("{0},{1},{2}", (base.Title == null) ? "" : base.Title, e.NavigationMode, str));
this.OnNavigatedFrom(e);
PerfUtil.EndLogMarker(MarkerEvents.TH_ONNAVIGATEDFROM_PAGE, string.Format("{0},{1},{2}", (base.Title == null) ? "" : base.Title, e.NavigationMode, str));
DeviceStatus.KeyboardDeployedChanged -= new EventHandler(this.OnKeyboardDeployedChanged);
Task rootTask = ApplicationHost.Current.RootTask;
rootTask.OnVisibleRegionChange = (ITask.VisibleRegionChanged) Delegate.Remove(rootTask.OnVisibleRegionChange, new ITask.VisibleRegionChanged(this.OnVisibleRegionChange));
Task task2 = ApplicationHost.Current.RootTask;
task2.OnSipVisibilityChange = (ITask.SipVisibilityChange) Delegate.Remove(task2.OnSipVisibilityChange, new ITask.SipVisibilityChange(this.OnSipVisibilityChange));
this._lastSipHeight = 0.0;
this._dictionary = null;
}
After a bit of debugging, I concluded that neither e or Application.Current.RootTask were null. After scratching my head, I looked at the code of the KeyboardDeployedChanged event handler:
public static event EventHandler KeyboardDeployedChanged
{
[SecuritySafeCritical] add
{
if (KeyboardDeployedSubscription == null)
{
KeyboardDeployedSubscription = new SubscriptionHandler(DeviceTypes.KeyBoard);
}
KeyboardDeployedSubscription.Changed += value;
}
[SecuritySafeCritical] remove
{
KeyboardDeployedSubscription.Changed -= value;
}
}
This code is poorly written. If the remove part of the handler is called before the add, KeyboardDeployedSubscription will be null and an exception will be raised. To test my theory, I subscribed to the event in App's constructor:
public App()
{
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;
DeviceStatus.KeyboardDeployedChanged += (sender, e) => { };
And sure enough, the exception was gone. Now, to understand why your code is triggering this issue, I backtraced to which part of the framework is supposed to subscribe to the event. The only candidate is the InternalOnNavigatedTo method.
Therefore, your issue is that OnNavigatedFrom is called even though OnNavigatedTo was never called.
Since you are strungling with the built-in auto navigation of Windows Phone to the page defined in WMAppManifest.xml, I tried to remove the auto navigation and it basically worked (no exception).
I just replaced
<DefaultTask Name="_default" NavigationPage="MainPage.xaml" />
with
<DefaultTask Name="_default" />
Not sure if this solves your problem but it at least doesn't crash anymore.
my question is simple, yet I couldn't find any answer of it in the net, maybe it's impossible to do...
The thing is that I have an ActionScript 3.0 application, and wanted to include a little one-line size textbox which showed all the trace() calls and such, which are shown in the console.
Has anyone got any idea of how can it be done? I would really appreciate it, as I have a full project with traces on it that I'd like to show, and it's now when I'm finishing that I'm realising I don't know how to do it :P
Of course not everything is lost, as I could just do my own class that showed there the messages, but it would be cleanier, and quicker not to have to replace all the trace() calls for my new class and method.
Regards and thanks in advance :)
I just did this last week.
There are logging frameworks for Flex out there. A shame, though, that Flex's logging only works in Debug mode. If you search SO for Flex logging you'll find various suggestions. None of them are amazing, IMO.
Finally I rolled my own by just creating a Log class with a static function that acts as a proxy for trace.
Something like:
public static myTrace(... args) : void { ... }
Then you just forward the args to trace but also to whatever other destination you want (e.g. an array of strings + dates) that you can then display in the log window.
Incidentally, I also used SwfAddress to trigger the log window whenever a certain parameter is added to the URL. Very handy.
Oh, what the heck.. here's the class. It just keeps the last 100 strings and there's also a "dump" function that you can invoke if you want to send the data to your server or just quickly print the entire history.
public class Log
{
public static var lines : ArrayList = new ArrayList();
public static const MAX_LINES : int = 100;
private static function logLine(line : String) : void
{
while (lines.length > MAX_LINES)
lines.removeItemAt(0);
lines.addItem({"line" : line, "time" : new Date()});
}
public static function logDump() : String
{
var ret : String = "";
for each (var entry : Object in lines.source)
{
ret = (entry.time as Date).toUTCString() + " " + entry.line + "\n" + ret;
}
return ret;
}
public static function debug(...args) : void
{
trace(args);
var line : String = "";
for (var i : int = 0; i < args.length; i++)
if (args[i] != null)
line += args[i].toString();
logLine(line);
}
}
Alternatively, you can use the ASDebugger
http://labs.flexperiments.nl/asdebugger-20-a-real-time-debugger-and-editor/
ASDebugger.debug( 'shallala' );
ASDebugger.debug_prop( variable );
Try to avoid using the debug display object option. The debugger can crash for complex objects (especially in flex)
You can probably do a simple replacement of 'trace(' to 'ASDebugger.debug('