Play the silverlight player from outside the silverlight object - asp.net

I have a simple Silverlight player that uses the MediaElement. For reasons out of my control, they want to be able to have all the play/pause/stop, volume controls etc. based in the ASP.NET code and not be built in Silverlight. I embed the Silverlight in my aspx as follows:
<object id="SilverlightPlayer" data="data:application/x-silverlight,"
type="application/x-silverlight-2" width="750" height="460" >
<param name="source" value="ClientBin/VideoPlayer.xap"/>
<param name="EnableGPUAcceleration" value="true" />
<param name="OnResize" value="HandleResize" />
<param name="autoUpgrade" value="true" />
<param name="initParams" id="SLInitParameters" value='video=MyVideo.wmv' />
</object>
I want to have the user click a "Play" button in the ASPX and it will tell the Silverlight player to play the video. (Same kind of thing for all the other buttons) I have been unable to find out how to do this anywhere since everyone it seems builds these controls into their Silverlight.
Any help is greatly appreciated.
UPDATE:
I am using the following to recreate the silverlight:
function CreateSilverlight(hostElement, source, initParams) {
var pluginId = hostElement.id + "PluginId";
hostElement.innerHTML = Silverlight.createObject(source, null, pluginId,
{
width: '750',
height: '460',
background: 'black',
isWindowless: true,
alt: '<!--Silverlight not installed-->',
data: 'data:application/x-silverlight,',
type: 'application/x-silverlight-2',
EnableGPUAcceleration: true,
version: '4.0',
autoUpgrade: true
},
{ onError: null, onLoad: null, OnResize: HandleResize },
initParams, hostElement.id);
}
So I don't have the reference to the object.

In the constructor of your silverlight page on which the media element appears, call:
HtmlPage.RegisterScriptableObject("player", this)
Then, you can add methods to your page like this:
[ScriptableMember]
public void Play()
{
this.MediaElement.Play();
}
[ScriptableMember]
public void Pause()
{
this.MediaElement.Pause();
}
[ScriptableMember]
public void Stop()
{
this.MediaElement.Stop();
}
Those [ScriptableMember] attributes are important. Then, from javascript, you can do:
var slApp = document.getElementById("SilverlightPlayer");
slApp.player.Play();
That would call the exposed "Play" method, which in turn tells the MediaElement to Play().

You can communicate from HTML to Silverlight via Javascript through the HtmlPage.Window.Invoke() method. Check out this link.

I didn't need to reload the silverlight control to get it to load a different video. I just needed to pass a new media path to the silverlight mediaElement.Source via the JS to silverlight bridge. I also solved my issue of loading a video passed to the page by adding to invoke a js function once the SL was loaded on the screen.

Related

Xamarin automatic sign-in credentials for Google Play's pre-launch report

I am building an Android application with Xamarin Forms 3 in Visual Studio 2017 and publishing to Google Play. Google Play offers automated testing (pre-launch report) but it cannot get past my sign-in screen.
Google Play has a place to enter the "username resource name", "password resource name", and "sign-in button resource name". I provided the Xamarin x:name for each control (txtEmail, txtPass, and btnSignIn), but apparently that is not correct, because the automated tester still can't get in and isn't even trying.
Here is my SignIn.xaml:
<Entry x:Name="txtEmail" Placeholder="email address" Keyboard="Email" />
<Entry x:Name="txtPass" IsPassword="True" />
<Button x:Name="btnSignIn" Text="Sign In" Clicked="OnSignInClicked" />
I've found these SO questions (here, here, and here) but they do not address my question from within a Xamarin Forms context. The first link seems particularly helpful but I do not know where to put that XML code.
It seems to me that Xamarin/C# is "compiled" into Android code and generates these XML files. How can I work with this process?
I understand an .APK file is just a ZIP file. Renaming the APK file I send to Google Play to .zip I'm able to browse the contents, but I do not see any XML code that makes sense.
For the moment, I added an extra "demo" button that, on click, puts a username and password into the fields and clicks the Sign In button. Google's automated tester likes this and can get in, but it's a terrible idea for human testing and I'd like to remove this workaround.
I've faced the same issue recently. I submitted an alpha build, enabled pre-launch report and got a policy violation error saying, that sign-in credentials are not provided. As it's stated in the question, I should have provided resource names along with the test credentials, but it wasn't obvious how to do it in Xamarin.Forms project. Nevertheless, I was able to workaround it using renderers. I know, it's a bit extreme to create a separate renderer and a control just to set id, but I really didn't want to change UI significantly, so, I created 3 empty controls:
public class UsernameEntry : Entry { }
public class PasswordEntry : Entry { }
public class LoginButton : Button { }
And used each of them in corresponding places on the login screen, instead of plain entries and the button.
Then I added ids.xml file into the Android project (Resource/values/ids.xml) and added 3 ids, one for every control:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="username_entry" type="id"/>
<item name="password_entry" type="id"/>
<item name="login_button" type="id"/>
</resources>
Finally, I created 3 renderers in the native Android project, one for each control. For example, this is how the UsernameEntryRenderer looks:
[assembly: ExportRenderer(typeof(UsernameEntry), typeof(UsernameEntryRenderer))]
namespace Android.Renderers
{
public class UsernameEntryRenderer : EntryRenderer
{
public UsernameEntryRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
// here I can reference the id created previously in ids.xml file
// and set the native android id property
Control.Id = Resource.Id.username_entry;
}
}
}
}
This is not the perfect way, but it worked well in my case. I didn't need to change the UI drastically or to introduce some hidden UI elements. Hopefully, this will be helpful for anyone facing similar problem.
Inspired by Yehor's answer, I was able to come up with a solution that uses Xamarin Effects without using custom controls.
First add ids.xml file into the Android project (Resource/values/ids.xml) and add 3 ids, one for every control. Make sure the Build action is set to AndroidResource and the Custom Tool is set to MSBuild:UpdateGeneratedFiles so the C# files can be generated automatically for the styles:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="username_entry" type="id"/>
<item name="password_entry" type="id"/>
<item name="login_button" type="id"/>
</resources>
Then define an enum so the effects can be defined easily:
public enum CustomIdType
{
None,
Username,
Password,
LoginButton
}
For the Android custom renderer, implement the following assign the android ID based on the custom effects.
[assembly: ResolutionGroupName("CustomRendererHandler")]
[assembly: ExportEffect(typeof(AndroidCustomIdEffect), "CustomIdEffect")]
namespace YOUR_ANDROID_NAMESPACE
{
public class AndroidCustomIdEffect : PlatformEffect
{
protected override void OnAttached()
{
// get autofill effect
var effect = (CustomIdEffect)Element.Effects
.FirstOrDefault(e => e is CustomIdEffect);
// assign android ID if custom ID effect is not null
if (effect != null) {
switch (effect.Type) {
case CustomIdType.Username:
Control.Id = Resource.Id.username_entry;
break;
case CustomIdType.Password:
Control.Id = Resource.Id.password_entry;
break;
case CustomIdType.LoginButton:
Control.Id = Resource.Id.login_button;
break;
}
}
}
protected override void OnDetached()
{
}
}
}
Then define a Routing Effect in your shared code to consume the Android custom renderer:
public class CustomIdEffect : RoutingEffect
{
public CustomIdType Type { get; set; }
public CustomIdEffect() : base("CustomRendererHandler." + nameof(CustomIdEffect))
{
}
}
Finally, to consume the Effects in your login page, simply add the Effects to the controls in XAML:
<Entry PlaceHolder="Enter Username">
<Entry.Effects>
<local:CustomIdEffect Type="Username"/>
</Entry.Effects>
</Entry>
<Entry PlaceHolder="Enter Password">
<Entry.Effects>
<local:CustomIdEffect Type="Password"/>
</Entry.Effects>
</Entry>
<Button Text="Login">
<Button.Effects>
<local:CustomIdEffect Type="LoginButton"/>
</Button.Effects>
</Button>
After that Google Pre-launch Report should be able to get pass the login screen if you provide the right sign-in credentials.

Flex Fullscreen Problems

I'm having problems with Full Screen in Flex.
Here's the Code:
private function toggleFullScreen(event:Event):void {
try {
switch (Application.application.stage.displayState) {
case StageDisplayState.FULL_SCREEN:
// If already in full screen mode, switch to normal mode.
Application.application.stage.displayState = StageDisplayState.NORMAL;
break;
default:
//If not in full screen mode, switch to full screen mode.
Application.application.stage.displayState = StageDisplayState.FULL_SCREEN;
break;
}
} catch (err:SecurityError) {
// ignore
}
}
I've already verified that this method is correctly being called, and that the SWITCH/CASE is working.
Still, after setting the displayState, nothing happens, and the attribute displayState remais with "normal" String.
I tested with previous versions of Firefox and Internet Explorer, but it didn't work either.
Does anybody know why is this happening? I'm new in flex and this code was developed by previous developers, that aren't working here anymore.
I've been searching a fix for weeks, but I didn't find anything that could help.
Thanks for the help.
Most likely you need to include the "allowFullscreen" in both of your param tag and embed attribute within the HTML template:
<object>
...
<param name="allowFullScreen" value="true" />
<embed ... allowfullscreen="true" />
</object>
And just a reference to the stage should be enough:
stage.displayState = StageDisplayState.FULL_SCREEN;

Display message from Servlet to JSF page

I'm trying to display success message in xhtml page from servlet but no luck, here's my code
In servlet i have
FacesContextFactory contextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
FacesContext facesContext = contextFactory.getFacesContext(request.getSession().getServletContext(), request, response, lifecycle);
facesContext.addMessage( "user:displaymessagesave", new FacesMessage("user saved successfully" ));
In xhtml page inside form i have written tag for display message form id=user
<h:message class="success" for="displaymessagesave" id="displaymessagesave" />
Saving to database is happening but its not displaying any message, please suggest where i'm going wrong.
It is not possible to access FacesContext from a servlet other than FacesServlet.
Recently I faced that same problem, and what I did was, on my servlet, put the messages in the Session:
List<String> msgs=(List<String>)request.getSession().getAttribute(KEY);
if (msgs==null)
{
msgs=new ArrayList<String>();
}
msgs.add("My new message");
request.getSession().setAttribute(KEY, msgs);
Then, on the xhtml view, I added a call to put these messages on FacesContext, and a growl element:
<h:outputText value="#{managed.prepareMessages()}"/>
<p:growl id="growl" showDetail="false" life="4000" />
Finally, the prepareMessages method takes them from session and add the messages to FacesContext:
public String prepareMessages()
{
List<String> msgs = (List<String>)FacesContext.getCurrentInstance()
.getExternalContext().getSessionMap().get(KEY);
if (msgs!=null)
{
for(String msg:msgs)
{
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(msg));
}
FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().remove(KEY);
}
return "";
}
It may not be an elegant solution, but is the only one I found...
Don't give the same id for message as the "for" component. If you just want a messageholder without attaching it to a valueholder than you should use the tag.
<h:messages class="success" id="displaymessagesave" />

How to show MSN status in Flex app form?

I have a flex business application and need to create some control that will show a small picture symbol of given user's MSN messenger status (online, away etc.)
Alternatively, how to insert an html page inside flex form?
There is a HTML code snippet on MSN site (supposed to be) doing exactly what I want, here it is:
<a target="_blank" href="http://settings.messenger.live.com/Conversation/IMMe.aspx?invitee=eb892994c712bb83#apps.messenger.live.com&mkt=ru-RU">
<img style="border-style: none;" src="http://messenger.services.live.com/users/eb892994c712bb83#apps.messenger.live.com/presenceimage?mkt=ru-RU" width="16" height="16" />
</a>
(it can be found here: http://settings.messenger.live.com/Applications/CreateHtml.aspx)
Also I'll need to replace eb892994c712bb83 in this snippet with user's cid code. How to find user's cid knowing his/her MSN account name is one more question...
Ok, week of investigation and some results:
1) MSN API exists for .NET and JavaScript - getting status from ASP.NET server side is possible;
2) there is an arcane ActiveX control named Name.NameCtrl that comes with Microsoft Office and can be used from JavaScript to retrieve MSN user status;
And
3) simplest way is to use htmlText property on a Flex control, for example on mx:TextArea control. Assigning HTML quoted in the question to htmlText property "just works". Comprehensive guide to htmltext property is here:
html_text_property_help
The HTML support within Flex (outside of AIR) is quite limited.
Another option is to use an Image control:
<s:Image id="msnLiveStatusIcon"
creationComplete="initStatus()"
click="openMSNLive()" />
where initStatus and openMSNLive are defined along the following lines:
private var userCID:String = "eb892994c712bb83";
protected function initStatus():void {
var iconURL:URLRequest = new URLRequest("http://messenger.services.live.com/users/"
+ userCID + "#apps.messenger.live.com/presenceimage?mkt=ru-RU");
msnLiveStatusIcon.source = iconURL;
// poll to check for updated status
var pollTimer:Timer = new Timer(60000); // once a minute
pollTimer.addEventListener(TimerEvent.TIMER,
function (e:TimerEvent):void {
msnLiveStatusIcon.source = null;
msnLiveStatusIcon.source = iconURL;
});
pollTimer.start();
}
protected function openMSNLive():void {
navigateToURL(new URLRequest("http://settings.messenger.live.com/Conversation/IMMe.aspx?invitee="
+ userCID + "#apps.messenger.live.com&mkt=ru-RU"),
"_blank");
}
The polling is optional. The anonymous function for the listener is used for brevity only, and not recommended for production.

ASP.MVC Ajax response returns form with some JS not executing

ASP.NET MVC Page has one link (Ajax.ActionLink), which gets the form to create and puts it in one of the div. I see the form in div but none of the JavaScript returned is getting executed. I am using JQuery validation and needs to run the validate() on the form so that returned form from AJAX request is validated.
Is there any setting or trick I am missing?
Thanks
If you're using jQuery, just replace the Sys.Mvc.MvcHelpers.updateDomElement with your own implementation.
(function ($) {
if (Sys && Sys.Mvc && Sys.Mvc.MvcHelpers) {
Sys.Mvc.MvcHelpers.updateDomElement = function My$updateDomElement(target, insertionMode, content) {
/// <param name="target" type="Object" domElement="true">
/// </param>
/// <param name="insertionMode" type="Sys.Mvc.InsertionMode">
/// </param>
/// <param name="content" type="String">
/// </param>
if (target) {
var $target = $(target);
switch (insertionMode) {
case Sys.Mvc.InsertionMode.replace:
$target.html(content);
break;
case Sys.Mvc.InsertionMode.insertBefore:
if (content && content.length > 0) {
$target.prepend(content);
}
break;
case Sys.Mvc.InsertionMode.insertAfter:
if (content && content.length > 0) {
$target.append(content);
}
break;
}
}
}
}
})(jQuery);
Since jQuery handles script tags correctly, that should fix your problem.
There is 2 ways I have it working now.
User the JQuery $.get and replace the html returned into the div. This is now executing the script for me.
Other option is remove the UpdateTargetId and ReplaceMode from the AjaxOptions and use call back to replace the html into div tag.

Resources