wpf 如何从另一个页面调用 MainWindows 上的方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29120527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to call a method on MainWindows from another Page
提问by John Majlstounn
I have MainWindow.xaml and another Page.xaml in same namespace
我在同一个命名空间中有 MainWindow.xaml 和另一个 Page.xaml
On MainWindow are textblock and frame.
在 MainWindow 上是文本块和框架。
Frame on MainWindow showing Page.xaml and on that Page is one Button.
MainWindow 上的框架显示 Page.xaml,该页面上只有一个 Button。
I want Call non-static method in MainWindow with that Button, but i dont know how :(
我想用那个按钮在 MainWindow 中调用非静态方法,但我不知道如何:(
For example:
例如:
MainWindow.xaml.cs
主窗口.xaml.cs
namespace wpfapp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
openframe();
}
private void openframe()
{
frame1.Source = new Uri("testapge.xaml", UriKind.Relative);
}
public void MyMethod()
{
textblock1.Text = "This text is showed on MainWindow if i click to the Button";
}
}
}
Page.xaml.cs
页面.xaml.cs
namespace wpfapp
{
public partial class Page : Page
{
public Page()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MainWindow trytocallit = new MainWindow();
trytocallit.MyMethod();
}
}
}
This of course doesnt work. Thank for your help!
这当然行不通。感谢您的帮助!
采纳答案by John Majlstounn
sorry for late reply, I have one simple resolution.
抱歉回复晚了,我有一个简单的解决方案。
- In Page.xaml create public string variable.
- If you click to the button on the page, variable gets the some value.
- Create new background theard on MainWindow and there runs an endless loop while (true) {..}
- The cycle control of the value public string variable again and again... with Thread.Sleep(10);
- If it finds a value that does something in MainWindow
- 在 Page.xaml 中创建公共字符串变量。
- 如果你点击页面上的按钮,变量会得到一些值。
- 在 MainWindow 上创建新的背景音乐并运行无限循环 while (true) {..}
- 一次又一次的循环控制值公共字符串变量... with Thread.Sleep(10);
- 如果它找到一个在 MainWindow 中做某事的值
It works too and simply for me :)
它也适用于我:)
回答by Ugur
As alternative and fast solution, you can use following code
作为替代和快速的解决方案,您可以使用以下代码
Usage:
用法:
MainWindow mainWindow = GetMainWindow();
Method:
方法:
public static MainWindow GetMainWindow()
{
MainWindow mainWindow=null;
foreach (Window window in Application.Current.Windows)
{
Type type = typeof(MainWindow);
if (window != null && window.DependencyObjectType.Name == type.Name)
{
mainWindow = (MainWindow)window;
if (mainWindow != null)
{
break;
}
}
}
return mainWindow;
}
回答by Cameron
You can do a couple of different things. You can implement something like Muds' answer, which is similar to the Singleton pattern.
你可以做一些不同的事情。你可以实现类似Muds' answer 的东西,它类似于Singleton 模式。
Another alternative is to use dependency injectionto give your Pageclass an instance of MainWindowwhen it is created.
另一种替代方法是使用依赖注入为您的Page类提供MainWindow创建时间的实例。
public class Page : Page
{
private MainWindow MainWindow;
public Page(MainWindow mainWindow)
{
InitializeComponent();
this.MainWindow = mainWindow;
// Other constructor stuff
}
// Other methods, event handlers, etc.
}
Typically with dependency injection, we rely on abstractions rather than concrete implementations (to reduce coupling).
通常对于依赖注入,我们依赖抽象而不是具体的实现(以减少耦合)。
public interface IMainWindowThatDoesSomething
{
void DoSomething();
}
public class MainWindow : Window, IMainWindowThatDoesSomething
{
// Constructor, methods, event handlers, etc. go here.
public void DoSomething()
{
// Implementation here.
}
}
public class Page : Page
{
private IMainWindowThatDoesSomething mainWindow;
public Page(IMainWindowThatDoesSomething mainWindow)
{
InitializeComponent();
this.mainWindow = mainWindow;
// Other constructor jazz.
}
private void UserDidSomethingAndMainWindowNeedsToReact()
{
mainWindow.DoSomething();
}
}
回答by Muds
well it doesn't sound right to do this, but if you have to get the object in memory rather than creating a new one..
好吧,这样做听起来不正确,但是如果您必须将对象保存在内存中而不是创建一个新对象..
but this dosent sound right .. tell us why u wanna do this so that we can suggest a better way
但是这听起来不错..告诉我们你为什么要这样做,以便我们可以提出更好的方法
--- just to make your case work .. do this ..
--- 只是为了让你的案例工作.. 这样做..
In main window --
在主窗口中——
public static MainWindow Instance { get; private set; }
static MainWindow()
{
Instance = new MainWindow();
}
private MainWindow()
{
InitializeComponent();
}
in app.xaml remove StartupUri="MainWindow.xaml"
在 app.xaml 中删除 StartupUri="MainWindow.xaml"
public App()
{
Startup += App_Startup;
}
void App_Startup(object sender, StartupEventArgs e)
{
TestApp.MainWindow.Instance.Show();
}
and in Page now you have access to static Instance ... call method on that
在 Page 现在你可以访问静态实例 ... 调用方法
回答by Scott Nimrod
Consider leveraging messaging with parameters to pass around data between your objects.
考虑利用带参数的消息传递在对象之间传递数据。
You can use an EventAggregatoror MessageBus.
您可以使用EventAggregator或MessageBus。
The idea is to have your user controls subscribe to events that they would like to respond to.
这个想法是让您的用户控件订阅他们想要响应的事件。
NOTE:
笔记:
I do this with viewmodels. However, I think it is a code-smell when adding this code to user-controls that are meant to have general use regardless of the application employing them.
我用视图模型来做这个。但是,我认为将此代码添加到旨在具有一般用途的用户控件时会产生代码气味,而不管使用它们的应用程序如何。
I use the Publish Subscribe patternfor complicated class-dependencies:
我对复杂的类依赖使用发布订阅模式:
ViewModel:
视图模型:
public class ViewModel : ViewModelBase
{
public ViewModel()
{
CloseComand = new DelegateCommand((obj) =>
{
MessageBus.Instance.Publish(Messages.REQUEST_DEPLOYMENT_SETTINGS_CLOSED, null);
});
}
}
Window:
窗户:
public partial class SomeWindow : Window
{
Subscription _subscription = new Subscription();
public SomeWindow()
{
InitializeComponent();
_subscription.Subscribe(Messages.REQUEST_DEPLOYMENT_SETTINGS_CLOSED, obj =>
{
this.Close();
});
}
}
You can leverage Bizmonger.Patternsto get the MessageBus.
您可以利用Bizmonger.Patterns来获取 MessageBus。
MessageBus
消息总线
public class MessageBus
{
#region Singleton
static MessageBus _messageBus = null;
private MessageBus() { }
public static MessageBus Instance
{
get
{
if (_messageBus == null)
{
_messageBus = new MessageBus();
}
return _messageBus;
}
}
#endregion
#region Members
List<Observer> _observers = new List<Observer>();
List<Observer> _oneTimeObservers = new List<Observer>();
List<Observer> _waitingSubscribers = new List<Observer>();
List<Observer> _waitingUnsubscribers = new List<Observer>();
int _publishingCount = 0;
#endregion
public void Subscribe(string message, Action<object> response)
{
Subscribe(message, response, _observers);
}
public void SubscribeFirstPublication(string message, Action<object> response)
{
Subscribe(message, response, _oneTimeObservers);
}
public int Unsubscribe(string message, Action<object> response)
{
var observers = new List<Observer>(_observers.Where(o => o.Respond == response).ToList());
observers.AddRange(_waitingSubscribers.Where(o => o.Respond == response));
observers.AddRange(_oneTimeObservers.Where(o => o.Respond == response));
if (_publishingCount == 0)
{
observers.ForEach(o => _observers.Remove(o));
}
else
{
_waitingUnsubscribers.AddRange(observers);
}
return observers.Count;
}
public int Unsubscribe(string subscription)
{
var observers = new List<Observer>(_observers.Where(o => o.Subscription == subscription).ToList());
observers.AddRange(_waitingSubscribers.Where(o => o.Subscription == subscription));
observers.AddRange(_oneTimeObservers.Where(o => o.Subscription == subscription));
if (_publishingCount == 0)
{
observers.ForEach(o => _observers.Remove(o));
}
else
{
_waitingUnsubscribers.AddRange(observers);
}
return observers.Count;
}
public void Publish(string message, object payload)
{
_publishingCount++;
Publish(_observers, message, payload);
Publish(_oneTimeObservers, message, payload);
Publish(_waitingSubscribers, message, payload);
_oneTimeObservers.RemoveAll(o => o.Subscription == message);
_waitingUnsubscribers.Clear();
_publishingCount--;
}
private void Publish(List<Observer> observers, string message, object payload)
{
Debug.Assert(_publishingCount >= 0);
var subscribers = observers.Where(o => o.Subscription.ToLower() == message.ToLower());
foreach (var subscriber in subscribers)
{
subscriber.Respond(payload);
}
}
public IEnumerable<Observer> GetObservers(string subscription)
{
var observers = new List<Observer>(_observers.Where(o => o.Subscription == subscription));
return observers;
}
public void Clear()
{
_observers.Clear();
_oneTimeObservers.Clear();
}
#region Helpers
private void Subscribe(string message, Action<object> response, List<Observer> observers)
{
Debug.Assert(_publishingCount >= 0);
var observer = new Observer() { Subscription = message, Respond = response };
if (_publishingCount == 0)
{
observers.Add(observer);
}
else
{
_waitingSubscribers.Add(observer);
}
}
#endregion
}
}
}
Subscription
订阅
public class Subscription
{
#region Members
List<Observer> _observerList = new List<Observer>();
#endregion
public void Unsubscribe(string subscription)
{
var observers = _observerList.Where(o => o.Subscription == subscription);
foreach (var observer in observers)
{
MessageBus.Instance.Unsubscribe(observer.Subscription, observer.Respond);
}
_observerList.Where(o => o.Subscription == subscription).ToList().ForEach(o => _observerList.Remove(o));
}
public void Subscribe(string subscription, Action<object> response)
{
MessageBus.Instance.Subscribe(subscription, response);
_observerList.Add(new Observer() { Subscription = subscription, Respond = response });
}
public void SubscribeFirstPublication(string subscription, Action<object> response)
{
MessageBus.Instance.SubscribeFirstPublication(subscription, response);
}
}

