How do I access MediaPlayerElement in a parent SplitView? - mvvm

I'm working on creating a radio app for Windows 10 on the UWP platform. I have a SplitView, with the right side (the SplitView Content) with a bottom margin. Down the bottom of the window I have a MediaPlayer (with TransportControls) down the bottom of the window.
The list of radio stations to play from are in a frame, which loads a certain page.
My question is, when I click on the radio station that I want to play, how do I set the source for this control, which exists in the parent window? I've tried to make a MediaPlayer object in the code behind and then maybe bind to that but I can't bind the physical XAML UI control to the MediaPlayer object. And even still, I can't access this object from another page in the app.
I'm a bit lost. Any help would be awesome :D

Do you use MvvMLight library ?
Because the solution in your case can be the Messaging logic.
Like the following code :
You create a message class with a Radio property (your business class) :
public class PlayRadioMessage
{
public PlayRadioMessage(Radio radio)
{
this.Radio = radio;
}
public Radio Radio { get; set; }
}
In your command on radio items (when click on a radio)
Messenger.Default.Send(new PlayRadioMessage(radio))
In your parent (SplitView content or MediaPlayer parent), you receive the message :
Messenger.Default.Register<PlayRadioMessage>(this, this.OnPlayRadio);
private void OnPlayRadio(PlayRadioMessage) {
// Set the source of your mediaPlayer with the radio property of your Message
}
Don't forget to unregister from messaging on unload of your view (if messaging is used in a View) :
Messenger.Default.Unregister(this);
Sorry for my english, I'm french :) ¯\_(ツ)_/¯

Related

Unity UI Button Doesn't Change Scene When Clicked

I am creating a game project with a main menu and 3 other scenes (MyWorld, ImportWorld, Lab). I've made the buttons on the main menu clickable to go the 3 other scenes, and want to make a back button to return to the main menu from the 3 scenes. I managed to make the back button work on the Lab scene, but when I tried the same steps and scripts to the MyWorld and ImportWorld, it doesn't bring to the main menu although they are clickable and changes color when hovered and clicked.
Below is the current script I am using for the Lab scene which is working. However I had a problem when I wanted to change the name of the text, suddenly it didn't worked. But luckily I didn't save and just undo which makes the button workable again.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ReturnMainMenu : MonoBehaviour
{
public void returnMenu()
{
SceneManager.LoadScene("MainScene");
}
}
Below is the script I used for the Main Menu scene which opens up the 3 other scenes and works fine.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ButtonTrigger : MonoBehaviour
{
public void btnMyWorld() //function when clicked, open My World scene
{
SceneManager.LoadScene("MyWorld");
}
public void btnImportWorld() //function when clicked, open Import World scene
{
SceneManager.LoadScene("ImportWorld");
}
public void btnLab() //function when clicked, open Lab scene
{
SceneManager.LoadScene("Lab");
}
public void btnQuit()
{
Application.Quit();
}
public void btnReturnMainScene() //function when clicked, should return to Main Menu
{
SceneManager.LoadScene("MainScene");
}
//tried adding this function to the Back buttons but didn't work
}
I've tried various scripts (including entering scene index and scene name), changed the canvas position in hierarchy to be on top, have Event System and RayCast target but nothing seems to fix the problem. Does anyone know what might be the cause that makes the button clickable, changes color when hover but doesn't load the Main Menu scene? And as I mentioned I had problems with the workable back button at Lab scene which stops working when I changed my text name, so maybe does it have anything to do with the project settings/scripts?
Maybe you didn't put the scene in build setting.
As in my understanding from the information provided, you have established a working code, which you use in multiple areas and scenes.
Understanding from the issue you are presented:
A button has been established and is clickable Returning a colour change to prove it.
The text your tried to change is about the scene change within your script.
public class ReturnMainMenu : MonoBehaviour
{
public void returnMenu()
{
UnityEngine.SceneManagement.SceneManager.LoadScene("MainMenu");
//Has to be written exactly as the Scene you are aiming to load up.
//Change the steps to include SceneManagement.
}
}
Look up if it is written down correctly keeping Case sensitivity in mind.
Check if the scene is added to your Build settings Found here!
Another area to take a look at is, if you have attached the script to your button, where it gets told on what it is supposed to be doing, OnClick -> do this action.
See attached below!
(Make sure it is enabled for both: Runtime / Editor)
Make sure the button has "Interactable" as checked (Ticked on)
If you copied the button from another scene, within unity more often than not there will be issues with it that it won't work as intended, for that I recommend making a copy of the button you wish to use and make a prefab out of it. (Which can be used in every area that you desire and scenes you desire).

Best way to organize OnClick events for Unity buttons?

enter image description here
Unity has a component called Button as part of its UI system which you can use to subscribe on-click events to it through the inspector which is incredibly useful.
However, when projects get larger, I run into trouble in many situations:
events subscribed this way in the inspector are not rearrange-able which makes buttons that have lots of events difficult to manage
changing the contents of the scripts used for events can cause the button to not recognize a function that was used for an event which means you have to re-reference it
if anything happens to the GameObject or prefab that stores the Button component such as it getting corrupt then all your events that were serialized onto the button would be wiped and you would need to re-reference all of them
the above points make debugging very very difficult
What are some ways I can work around the problems I've listed above?
Inject event functions inside the code:
public Button playButton; // set button in inspector
public void Start()
{
playButton.onClick.AddListener(() =>
{
transform.position = point1;
// do something..
});
}

word object model - active document event when clicking on FILE

I'm developing an MS Word add-in. In newer MS Word editions, there is the "FILE" option in the menu bar which opens an interface where you can select a recent document to open, open a new one, or an existing one. I am trying to find a way, through which I can know WHEN the user "leaves" the current document he is editing clicking on the FILE menu of Word. I cannot seem to find such an event. Is there a way to achieve this ?
The WindowDeactivate does not fulfill this purpose.
The reason I want to do this, is because for a custom spellchecker I'm writing, I'm highlighting the wrong words in an transparent (click through as well) form. So when the user in a recent version of Word clicks the FILE menu, the highlights are still there, as seen in the screenshot
TL:DR; is there a way to detect in MS Word when the user clicks the FILE option in the menu and the current document is not visible? I'm using add-in-express, so all the relevant word object model API is available.
I wonder how can I solve this, any help is appreciated.
edit: screenshot
Yes, you can detect and then execute code both when the File menu is clicked (displaying the Backstage View) and when the View's return arrow is clicked to remove the Backstage View and display the document. To do this use the onShow and onHide attributes with callbacks via a custom XML ribbon in your VSTO project (this will not work with a ribbon made with the Visual Designer).
Reference material can be found here:
Performing Actions When the Backstage View is First Displayed or Hidden
As this article uses VBA to expand on the concepts involved, I built a sample project demonstrating how onShow works using C# and Word 2016 (the documentation was written for Office 2010, but onShow and onHide will work in later versions of Word).
Solution Tree
Custom XML Ribbon (BackstageRibbon.xml)
Note that the <backstage> node, which activates the onShow attribute for the callback, follows the <ribbon> node in the XML.
<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui"
onLoad="Ribbon_Load">
<ribbon>
<!--Ribbon XML goes here-->
</ribbon>
<backstage onShow="onShow">
</backstage>
</customUI>
Ribbon Code (BackstageRibbon.cs)
A bunch of this code is boilerplate, however public void onShow is the callback that executes your code based on the onShow attribute in the ribbon's custom XML. Also, public string GetCustomUI is where the C# is told to find the XML.
namespace Backstage_Events
{
[ComVisible(true)]
public class BackstageRibbon : Office.IRibbonExtensibility
{
private Office.IRibbonUI ribbon;
public BackstageRibbon()
{
}
#region IRibbonExtensibility Members
public string GetCustomUI(string ribbonID)
{
return GetResourceText("Backstage_Events.BackstageRibbon.xml");
}
#endregion
#region Ribbon Callbacks
//Create callback methods here. For more information about adding callback methods, visit https://go.microsoft.com/fwlink/?LinkID=271226
public void Ribbon_Load(Office.IRibbonUI ribbonUI)
{
this.ribbon = ribbonUI;
}
public void onShow(object contextObject)
{
//Code to be executed before Backstage View displays goes here
MessageBox.Show("Backstage Display Event Triggered!");
}
#endregion
Helpers //Region
}
}
ThisAddin.cs
You will also need to add:
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
return new BackstageRibbon();
}
after the ThisAddIn_Startup and ThisAddIn_Shutdown private voids in the ThisAddin.cs class to instantiate the custom ribbon.
Word will fire the Application.DocumentOpen event - you can see it live in OfficeSpy (I am its author - click Application button, go to the Events tab, look at the log at the bottom of the window).

multiple view models in a single page mvvmcross

I am trying to make an App for multiple platforms using Xamarin. The App uses the Mvvm structure and MvvmCross.
Currently, I have various View Models and they all bind great (using MvvmCross), as long as they are in separate pages.
However, I would like to make a single page that references multiple View Models. For example, a page that has few buttons each binding to methods in different View Models.
I understand that to do this I should:
1) Divide the screen to different views.
2) Assign the buttons to different views according to their View Model.
I am not sure how can I divide the screen? Are fragments the answer?
Also, does this mean a View Model that would know about all view models in the page is necessary?
My current work around is having tabs in all pages that change the current view model of that page, as follow:
public ICommand VM1Command
{
get { return new MvxCommand(() => ShowViewModel<ViewModel1>()); }
}
public ICommand VM2Command
{
get { return new MvxCommand(() => ShowViewModel<ViewModel2>()); }
}
public ICommand VM3Command
{
get { return new MvxCommand(() => ShowViewModel<ViewModel3>()); }
}
This is pretty ugly, I would really appreciate if anyone could refer me to somewhere where this is explained or even better tell me how to do it.
Cheers!
The SpheroViewModel is used in the SpheroView (see: SpheroView.cs). This View is a MvxBindingTabActivityView. So it uses an Android TabHost to display the Subviews as Tab. The setup is done in the lines 30 - 48. For each SubViewModel you have an own view (e.g. SpheroAccelMovementView.cs) that binds and displays the separate data.
For more Details on Tabs and MvvMCross and different Platforms have a look at N = 25 - Video Tutorial. There are perhaps some API changes since stuart has recored the video. But it explains the general idea of tabs and subviewmodels.

MVVM: Handling list item navigation with keyboard in Windows 8

I am totally new to Windows 8 development and I am now facing an issue mixing touch and keyboard navigation using MVVM Light.
So I have a list of view models in a grid view and whenever one of those is selected, navigation to the selected view model is activated. This works totally fine with touch or a mouse, but with a keyboard it can get really confusing. Indeed, the natural behavior would be to navigate the list with the arrows and hit enter when I want to display the item, but here instead, navigation will be activated when simply changing item with the arrow keys which is really confusing for the user.
So how could I do so the navigation could be activated on selection with touch and mouse and with a combination of selection and enter key with the keyboard?
Here is the code I use.
ViewModel:
public ReleaseViewModel SelectedRelease
{
get
{
return selectedRelease;
}
set
{
if(selectRelease != value)
{
selectedRelease = value;
}
// Navigation code here
}
}
View:
<GridView
ItemsSource="{Binding Releases}"
ItemTemplate="{StaticResource ReleaseTemplate}"
ItemContainerStyle="{StaticResource GridViewItemStyle}"
Grid.ColumnSpan="2"
Grid.Row="2"
Padding="116,0,40,46"
SelectedItem="{Binding SelectedRelease, Mode=TwoWay}"/>
In my opinion, coding with the MVVM pattern does not mean that everything code-related should be done in the model. Operations which is related UI beaviors (like navigation) should still be done in the view (the codebehind), by using the available events from the control. Like the GridView's events mouse and keyboard events.
Many may not agree with me on that, but after working by the MVVM pattern for several years in both WPF and Silverlight, I must say that a good combination between the UI-behavior (view) and the control's logic/functionability (model), you will also be forced to put several stuff which concerns the UI only to the codebehind. At least, this is my opinion.
What you could do is to create a class which inherits GridView (let's call it MyDataGrid).
Then you can use the OnKeyDown override and have the navigation go vertica when pressing enter.
You can actually make the MyDataGrid look and behave "out-of-the-box" just like you want so there are no extra code if you want to use the same grid behavior another place in your app (or another app).
The best way I finally found is to use some code behind. But instead of directy navigating from the UI I kept navigation logic in the view models.
So I simply hooked up the ItemClick event from the GridView and in the event handler I casted the Page data context to my view model and then I simply executed the command from the view model. This is not easy to maintain but it surely preserve the separation of concerns of MVVM.
private void GridView_ItemClick(object sender, ItemClickEventArgs e)
{
MyViewModel vm = (MyViewModel)this.DataContext;
if(vm.NavigateToSelectionCommand.CanExecute(null))
{
vm.NavigateToSelectionCommand.Execute(e.ClickedItem);
}
}
Still I hope a cleaner and more maintainable solution will come up with time.