RoutedEventArgs and AllFramesEventArgs - kinect

I am trying to call a function whose parameters are object sender and RoutedEventsArg e. I need those parameters since I have created a button on the main window related to this function and when I click the button it links to my function.
protected void StartRecord(object sender,RoutedEventsArg e)
{
// some stuff that creates a button and then does stuff
}
In another function, I need to call the above function stated above, but this second function has a parameter of AllFramesReadyArg e, not RoutedEventsArg e. So how do i call out the first function
void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
this.StartRecord(sender, e);
// does not work since parameter calls for RoutedEventArgs
}

Your StartRecord is not part of the Kinect Toolbox. You appear to have written it and given it those two arguments. It doesn't need them, nor do you necessarily need the function.
You also do not want to be calling StartRecord in AllFramesReady. The AllFramesReady callback is fired every time all the frames are ready for processing (hence the function name), which happens roughly 30 times a second. You only need to tell it to record once.
Per your other question, StartRecord is a callback to a button -- it shouldn't be called in code. It is called when the user hits the associated button.
Just looking at the Kinect Toolbox code and the callbacks, your code should look something like this:
KinectRecorder _recorder;
File _outStream;
bool _isRecording = false;
private void KinectSetup()
{
// set up the Kinect here
_recorder = new KinectRecorder(KinectRecordOptions.Skeleton, _outStream);
// some other stuff to setup
}
private void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
SkeletonFrame skeleton;
if (_isRecording && skeleton != null)
{
_recorder.Record(skeleton);
}
}
public void StartRecord(object sender, RoutedEventsArg e)
{
_isRecording = !_isRecording;
}

Related

CompositionTarget.Rendering doesn't like my event handler in XAML

I'm converting a Windows Phone 7 app to Windows Store, so I'm moving over to Xaml. I have a method that runs at a certain point to update the data on the screen. It either assigns or removes an event handler delegate to the CompositionTarget.Rendering event. The message I get is No overload for 'OnCompositionTargetRendering' matches delegate 'System.EventHandler' '
Here's what I have:
private void CheckCompleted()
{
Color completeColor;
if (this.DecryptedText.ToString().ToUpper() == this.ThisPuzzle.QuoteText.ToUpper())
{
// We're done!!! ...
CompositionTarget.Rendering -= this.OnCompositionTargetRendering;// new EventHandler(this.OnCompositionTargetRendering);
...
}
else
{
...
CompositionTarget.Rendering += this.OnCompositionTargetRendering;// new EventHandler(this.OnCompositionTargetRendering);
...
}
}
protected void OnCompositionTargetRendering(object sender, EventArgs args)
{
this.DisplayTime();
if (ThisPuzzle != null)
{
foreach (UIElement thisElement in Letters.Children)
{
...
}
}
}
If you check the documentation CompositionTarget.Rendering is of type EventHandler<object> in Windows Store apps and not of type EventHandler as in Silverlight.
This means you need to change the signature of your event handler accordingly to:
protected void OnCompositionTargetRendering(object sender, object args)

What the right time for registering listener for Share/Search charms

I need to register different share charm listener for every page. I have 2 pages. I added following code in every one:
DataTransferManager.GetForCurrentView().DataRequested += App_DataRequested;
I added it in constructor of one page and in UserControl_Loaded event of another (first page just doesn't have UserControl_Loaded so why I added it directly to constructor). At the moment when second page tryting to load, I got exception:
WinRT information: An event handler has already been registered
Additional information: A method was called at an unexpected time.
Where should I place it and what is "right" time to do this??
Also it looks confusing that we have different DataTransferManager for every view, but only one is active at current time. Ever more, I noticed, if you add only one listener for first page, other pages will share this listener anyway. If I have only one shared listener for all pages, is it correct register it in app.xaml.cs?
The way I resolved this issue was to deregister the event in the onNavigatedfrom event as below:
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested -= App_DataRequested;
base.OnNavigatedFrom(e);
}
In BasePage.cs in constructor I added
public BasePage()
{
if (!_isListenToDataRequested)
{
_isListenToDataRequested = true;
DataTransferManager manager = DataTransferManager.GetForCurrentView();
manager.DataRequested += AppDataRequested;
}
}
private async void AppDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
IShareable shareable = Frame.Content as IShareable;
if (shareable != null)
{
DataRequestDeferral deferral = args.Request.GetDeferral();
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => shareable.AppDataRequested(sender, args));
deferral.Complete();
}
}
And all my pages look like
public sealed partial class ContentPage : IShareable
{
public void AppDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{...}
}
Another solution was run this as below
private DataTransferManager dataTransferManager;
Put this in page loaded event
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new DispatchedHandler(() =>
{
this.dataTransferManager = DataTransferManager.GetForCurrentView();
this.dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(this.OnDataRequested);
}));
And
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// Unregister the current page as a share source.
this.dataTransferManager.DataRequested -=
new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>
(this.OnDataRequested);
}
I'd suggest doing it in the navigating events, the OnNavigatingFrom event will be triggered before the OnNavigatingTo of the page you're going to so you won't have this problem.
protected override Task OnNavigatingTo(WinRTXamlToolkit.Controls.AlternativeNavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested += dataTransfer_DataRequested;
return base.OnNavigatingTo(e);
}
protected override Task OnNavigatingFrom(WinRTXamlToolkit.Controls.AlternativeNavigatingCancelEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested -= dataTransfer_DataRequested;
return base.OnNavigatingFrom(e);
}
//Note: This is the WinRT Xaml Toolkit version of the events, but the standard events will work the same way.

Calling a async method multiple times with different parameter Silverlight 4.0

I am calling a async method having a single parameter, It will return me the result according to parameter. I am calling that method more than one time with different parameter value, but in Completed event i am getting the same value for all.
client.ListAllLookupValuesByTypeCompleted += client_ListAllAddressFormatCompleted;
client.ListAllLookupValuesByTypeAsync("AddressFormat");
client.ListAllLookupValuesByTypeCompleted += client_ListAllPhoneFormatCompleted;
client.ListAllLookupValuesByTypeAsync("PhoneFormat");
void client_ListAllAddressFormatCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
{
cmbAddressFormat.ItemsSource = e.Result;
}
void client_ListAllPhoneFormatCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
{
cmbPhonePrintFormat.ItemsSource = e.Result;
}
But getting same value in e.Result.
any suggetions. Thanks.
Your method may return a different value based on the first parameter, but both handlers will be called at the same time every time, regardless of what you send it. If this is a standard webservice reference, then you should see an object userState parameter available for you and this can be used to determine what to do.
client.ListAllLookupValuesByTypeCompleted += client_ListAllLookupValuesCompleted;
client.ListAllLookupValuesByTypeAsync("AddressFormat", true);
client.ListAllLookupValuesByTypeAsync("PhoneFormat", false);
void client_ListAllLookupValuesCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
{
// e.UserState will either be false or true
if ((bool)e.UserState)
cmbAddressFormat.ItemsSource = e.Result;
else
cmbPhonePrintFormat.ItemsSource = e.Result;
}

CF keyDown event (timed)

I need an event for my CF application, that would trigger after user has pressed an held his finger on the control for 2 seconds. What event can i use, since keyDown event is already used.
Well, KeyDown is pretty irrelevant for capturing the length of time a finger is pressed. The use of the finger relates to the events Click, MouseDown, MouseUp and MouseMove.
To get the behaviour you're after, the events you should be interested in are MouseDown and MouseUp.
I suggest the best way to do this would be to create your own control base class. Here's one I made earlier (not tested, but should give you a general idea of what to do):
public partial class BaseControl : UserControl
{
public BaseControl()
{
InitializeComponent();
base.MouseDown += new MouseEventHandler(BaseControl_MouseDown);
base.MouseUp += new MouseEventHandler(BaseControl_MouseUp);
MouseHeldTimer = new Timer();
MouseHeldTimer.Interval = 2000;
MouseHeldTimer.Tick += new EventHandler(mouseHeldTimer_Tick);
}
protected Timer MouseHeldTimer;
protected bool MouseIsDown;
void mouseHeldTimer_Tick(object sender, EventArgs e)
{
this.MouseHeldTimer.Enabled = false;
if (this.MouseHeldDown != null)
{
this.MouseHeldDown(sender, e);
}
}
void BaseControl_MouseDown(object sender, MouseEventArgs e)
{
this.MouseHeldTimer.Enabled = true;
}
void BaseControl_MouseUp(object sender, MouseEventArgs e)
{
this.MouseHeldTimer.Enabled = false;
}
public event MouseHeldDownHandler MouseHeldDown;
public delegate void MouseHeldDownHandler(object sender, EventArgs e);
}
Basically, the MouseHeldTimer will start with an interval of 2 seconds the moment the user touches their finger to the screen. If the user lifts their finger the timer is stopped. If the user's finger is down for longer than 2 seconds, the delegate event MouseHeldDown will fire. You can then capture this event on your form by doing the following:
control.MouseHeldDown+= new EventHandler(control_MouseHeldDown);
Alternatively, if you only care about the form, you can just use the Form's DoubleClick event as that will fire after holding the mouse down for a second or two.

Best practices for converting WCF calls to async WCF calls

I am running into issues when trying to convert all my normal WCF calls to async WCF calls. I'm finding I have a refactor a lot of code and not sure exactly how to do it. I have used the method that I found here but running into issues where I need things to happen in order.
private void btnSave_Click(object sender, RoutedEventArgs e)
{
List<Item> itemList = GetList();
foreach(Item i in itemList)
{
DoSomeWork(i);
if(i.SomeID == 0)
{
DoSomeMoreWork(i);
}
UpdateRecord(i) // this can't execute until the above code is complete
}
}
private void DoSomeWork(Item i)
{
// call async method
}
private void DoSomeMoreWork(i)
{
// call async method
}
private void UpdateRecord(item i)
{
// call async method
}
What is the best way to refactor code to work in an asyncronous way, or do I need to completely rethink my logic? Do I really have to insert counters and switches everywhere to make sure certain things are done before other things execute?
EDIT: The reason I'm doing this is in the next couple months, we are converting this WPF application to Silverlight, which requires async calls. So I'm trying to convert our regular WCF calls to async in preparation. I'm finding it requires a different way of thinking.
For what you're doing, I'd say the real place to handle things is to make a single call to the service per item, not 3.
Preferably, if the list of items is not huge, make a single call to the service with the whole list...
private void btnSave_Click(object sender, RoutedEventArgs e)
{
List<Item> itemList = GetList();
foreach(Item i in itemList)
{
DoAllTheWorkAndUpdate(i);
}
}
or...
private void btnSave_Click(object sender, RoutedEventArgs e)
{
List<Item> itemList = GetList();
foreach(Item i in itemList)
{
if(i.Id == 0)
{
DoLotsOfWorkAndUpdate(i);
}
else
{
DoSomeWorkAndUpdate(i);
}
}
}
or...
private void btnSave_Click(object sender, RoutedEventArgs e)
{
List<Item> itemList = GetList();
DoTheWorkOnTheWholeList(itemList);
}
In other words, it feels like some of your responsibilities may be misplaced - I generally prefer to make services where I can make a single call to them. Then, the asynchronous nature is irrelevant, because you're not performing a sequence of events.
Take a look at Juval Lowy's (author of Programming WCF Services) website for examples of how to achieve asynchronous programming in WCF. The downloads are free; you just have to provide your email address.
I am perhaps a bit puzzled as to why you need to use asynchronous WCF operations when you need things to be synchronous inside the loop.
If you are just using the async methods to help keep the UI from hanging, then you could just use a BackgroundWorker that supports progress updates to keep the UI up to date, and not use Async WCF calls.
You should also be able to call your various functions from the Completed events for the Async methods.
Just hook up event handlers to the completed events and then pass your Item object as the userState parameter when you start the async WCF call. This way you will have it as a parameter when each of the Completed events fires. That way you will only be doing the next step in your processing as the previous async call completes.
I don't know if this really is answering your question though.
Try using this
http://ayende.com/Blog/archive/2008/03/29/WCF-Async-without-proxies.aspx
the approach that definitely works.
If you're not using Silverlight, you can block your thread in one method until the other methods complete, using, say, a ManualResetEvent. But that won't work in Silverlight, since all WCF calls happen on the main UI thread, so if you block that thread, everything blocks. A better approach is to do something like this, using callbacks:
public delegate void OperationCallback();
private void btnSave_Click(object sender, RoutedEventArgs e)
{
List<Item> itemList = GetList();
foreach (Item i in itemList)
{
DoSomeWork(i, () =>
{
if (i.SomeID == 0)
{
DoSomeMoreWork(i, () =>
{
UpdateRecord(i);
});
}
else
{
UpdateRecord(i);
}
});
}
}
private void DoSomeWork(Item i, OperationCallback callback)
{
// call async method then callback when it completes.
callback();
}
private void DoSomeMoreWork(Item i, OperationCallback callback)
{
// call async method, then callback when it completes.
callback();
}
private void UpdateRecord(Item i)
{
// call async method
}
It's certainly not as clear as the synchronous version, but if you use lambda expressions as much as possible, it's still possible to keep the control flow fairly readable.
Add 2 properties to Item called SomeWorkDone and SomeMoreWorkDone both as booleans. Create methods to handle both DoSomeWorkCompleted and DoSomeMoreWorkCompleted. In those methods, set the respective boolean properties to true and call UpdateRecord. Within UpdateRecord, ensure that both Done properties are true and then complete the calls.
You'll have some possible contention issues but this should get you going.