到目前为止,我有一个 UWP 项目有2页。 MainPage.xaml
是应用程序的基本布局(汉堡菜单,搜索栏等)。此MainPage的另一部分包含加载另一页LandingPage.xaml
的框架。我想从MainPage.xaml中的AutosuggestBox捕获用户输入,并在LandingPage.xaml上显示结果(它位于MainPage.xaml中的一个框架中)。
我尝试继承MainPage,但不允许这样做。
答案 0 :(得分:3)
虽然玛丽安的回答肯定有效,但我认为它远非“干净”。或者“好”'代码。
首先,您应该在UWP应用程序中实现MVVM模式(如果您还没有这样做)并使用依赖注入框架。一个非常基本的,易于理解的是MVVMLight,而更复杂的选择框架可能是Autofac。我建议你从前者开始,先把它包起来要快得多。
在MVVM中,有一个概念可以解决你的问题:信使。我不想在这里详细介绍细节,因为已经有很多非常好的资源来写这个由比我更聪明的人写的。例如,来自MVVMLight本人的作者的这篇文章:https://msdn.microsoft.com/en-us/magazine/jj694937.aspx(我从2013年开始就知道它并谈论Windows 8,但不要担心,概念也是一样的。)
这个想法是,不同的ViewModel不应该彼此之间有严格的依赖关系 - 它使得单元测试(这是首先做MVVM的要点之一)很难。所以在你的情况下,你应该有两个ViewModel:MainViewModel和LandingViewModel。一个用于MainPage,一个用于LandingPage。现在,您应该在MainPage的AutoSuggestBox的QuerySubmitted事件的代码隐藏中实现一个处理程序,并在MainViewModel中调用一个函数。在该函数中,您将使用来自AutoSuggestBox的字符串实例化一个新消息(您可以通过数据绑定到它或通过QuerySubmitted的事件处理程序获取它,它取决于您)并通过传信人。在LandingViewModel中,您可以订阅这个确切的消息,然后它只需几行就可以通过LandingPage上的数据绑定显示收到的消息。
我知道对于像这样非常基本的事情来说,这看起来很麻烦,特别是如果你将它与玛丽安的直接解决方案进行比较。但请相信我,从长远来看编写干净的代码,很好地分离,容易单元测试的ViewModels将弥补你最初需要付出的额外努力才能让它们工作。在两个ViewModel之间建立这样的系统之后,添加第三个(我认为你很快就需要做)这个系统绝对是微不足道的,可以很快完成。
答案 1 :(得分:2)
如果您不使用MVVM,我建议在x:FieldModifier="public"
上添加AutoSuggestBox
,并向MainPage添加公共静态属性以存储其实例。
<强> MainPage.xaml.cs中强>
public static MainPage Current { get; private set; }
public MainPage()
{
Current = this;
// Rest of your code in ctor
}
然后您可以使用
访问它string text = MainPage.Current.NameOfYourAutoSuggestBox.Text;
答案 2 :(得分:0)
只需使用您自己的简单消息传递机制,如下所示:
public class Messages {
public static Messages Instance { get; } = new Messages();
private readonly List<Subscription> subscriptions;
private Messages() {
subscriptions = new List<Subscription>();
}
public void Send<T>(T message) {
var msgType = message.GetType();
foreach (var sub in subscriptions)
if (sub.Type.IsAssignableFrom(msgType))
sub.Handle(message);
}
public Guid Subscribe<T>(Action<T> action) {
var key = Guid.NewGuid();
lock (subscriptions) {
subscriptions.Add(new Subscription(typeof(T), key, action));
}
return key;
}
public void Unsubscribe(Guid key) {
lock (subscriptions) {
subscriptions.RemoveAll(sub => sub.Key == key);
}
}
public bool IsSubscribed(Guid key) {
lock (subscriptions) {
return subscriptions.Any(sub => sub.Key == key);
}
}
public void Dispose() {
subscriptions.Clear();
}
}
internal sealed class Subscription {
internal Guid Key { get; }
internal Type Type { get; }
private object Handler { get; }
internal Subscription(Type type, Guid key, object handler) {
Type = type;
Key = key;
Handler = handler;
}
internal void Handle<T>(T message) {
((Action<T>)Handler).Invoke(message);
}
}
它既小又简单,但是它允许并行订阅不同的消息,并按消息类型分开。在与您类似的情况下,您可以通过以下方式订阅:
Messages.Instance.Subscribe<TextChangeArgs>(OnTextChanged);
和您的其他页面可以使用以下方式发送消息:
Messages.Instance.Send(new TextChangeArgs(...));
只有所有对此特定消息类型感兴趣的用户才能收到该消息。您可以(当然应该)也退订。在现实世界中,还可能需要更多错误处理。
如有必要,您可以添加其他功能,例如轻松进行节流(以避免在给定的时间段内出现太多连续的消息)。