问题
I'm developing a UWP application with two window pages on two separate screens.
It's include:
- Mainpage.xaml
- Mainpage.xaml.cs
- Page2.xaml
- Page2.xaml.cs
My scenario:
- get the mouse position(X) while moving on the secondary screen (Page2).
- write it in the text block on the first screen (MainPage), Changing at the same time.
In MainPage.xaml
<Page
x:Class="LineDraw.MainPage"
xmlns:local="using:LineDraw"
...
..
<Grid>
<TextBlock Name="textblock" Text="N/A" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="100" />
</Grid>
</Page>
In MainPage.xaml.cs
public sealed partial class MainPage : Page
{
public double Xpage2;
public MainPage()
{
this.InitializeComponent();
newpage();
}
private async void newpage()
{
int NewWindowid = 0;
int Windowid = ApplicationView.GetForCurrentView().Id;
CoreApplicationView newView = CoreApplication.CreateNewView();
await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Frame newframe = new Frame();
newframe.Navigate(typeof(Page2), this); // this means existing MainPage object.
Window.Current.Content = newframe;
Window.Current.Activate();
NewWindowid = ApplicationView.GetForCurrentView().Id;
});
bool available = ProjectionManager.ProjectionDisplayAvailable;
ProjectionManager.ProjectionDisplayAvailableChanged += (s, e) =>
{
available = ProjectionManager.ProjectionDisplayAvailable;
};
await ProjectionManager.StartProjectingAsync(NewWindowid, Windowid);
}
public void copyX(double Xpage2)
{
textblock.Text = $"X = {Xpage2}";
}
}
In Page2.xaml.cs
public sealed partial class Page2 : Page
{
MainPage mainpage;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
mainpage = e.Parameter as MainPage;
base.OnNavigatedTo(e);
}
public Page2()
{
this.InitializeComponent();
Window.Current.CoreWindow.PointerMoved += CoreWindow_PointerMoved;
}
public void CoreWindow_PointerMoved(CoreWindow sender, PointerEventArgs args)
{
Point ptr = args.CurrentPoint.Position;
double Xpage2 = ptr.X;
mainpage.copyX(Xpage2);
}
I did the code above but the result is the following error:
System.Exception
HResult=0x8001010E
Message=The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
Source=<Cannot evaluate the exception source>
StackTrace:
<Cannot evaluate the exception stack trace>
I want to get the textblock
(UI control) in main.xaml
from Page2.xaml.cs
.
I need a solution , How can I do that?
回答1:
You're trying to run a method (mainpage.copyX()) that has been running in another context. I don't know why you created another view, if you can just run this code on the MainView of CoreApplication. In MainPage.xmal.cs:
await CoreApplication.MainView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Frame newframe = new Frame();
newframe.Navigate(typeof(Page2), this);
Window.Current.Content = newframe;
Window.Current.Activate();
NewWindowid = ApplicationView.GetForCurrentView().Id;
});
await CoreApplication.MainView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Point ptr = args.CurrentPoint.Position;
double Xpage2 = ptr.X;
mainpage.copyX(Xpage2);
});
If you create another view, you need somehow share this resource in order for everyone execute on the same context.
回答2:
For your scenario, the better way is sending message via MessagingCenter. MessagingCenter
is used to pass parameter between two class. And I have create code sample base on your code that you could refer.
MainPage.Xaml.cs
private async void newpage()
{
int NewWindowid = 0;
int Windowid = ApplicationView.GetForCurrentView().Id;
CoreApplicationView newView = CoreApplication.CreateNewView();
await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Frame newframe = new Frame();
newframe.Navigate(typeof(OtherPage), this); // this means existing MainPage object.
Window.Current.Content = newframe;
Window.Current.Activate();
NewWindowid = ApplicationView.GetForCurrentView().Id;
});
bool available = ProjectionManager.ProjectionDisplayAvailable;
ProjectionManager.ProjectionDisplayAvailableChanged += (s, e) =>
{
available = ProjectionManager.ProjectionDisplayAvailable;
};
await ProjectionManager.StartProjectingAsync(NewWindowid, Windowid);
SubMessage();
}
private void SubMessage()
{
MessagingCenter.Subscribe<OtherPage, string>(this, "Tag", async (s, arg) =>
{
await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
textblock.Text = arg;
});
});
}
OtherPage.Xaml.cs
public OtherPage()
{
this.InitializeComponent();
Window.Current.CoreWindow.PointerMoved += CoreWindow_PointerMoved;
}
public void CoreWindow_PointerMoved(CoreWindow sender, PointerEventArgs args)
{
Point ptr = args.CurrentPoint.Position;
double Xpage2 = ptr.X;
MessagingCenter.Send<OtherPage, string>(this, "Tag", Xpage2.ToString());
}
And you could copy the MessagingCenter
class directly from the above link. For more detail you could refer MessagingCenter
official document.
来源:https://stackoverflow.com/questions/53991071/how-to-get-a-certain-ui-control-from-two-classes