如何从另一个页面调用 MainWindow 上的方法
How to call a method on MainWindows from another Page
我在同一个命名空间中有 MainWindow.xaml 和另一个 Page.xaml
MainWindow 上有文本块和框架。
MainWindow 上的框架显示 Page.xaml,该页面上有一个按钮。
我想用那个按钮在 MainWindow 中调用非静态方法,但我不知道如何:(
例如:
MainWindow.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
namespace wpfapp
{
public partial class Page : Page
{
public Page()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MainWindow trytocallit = new MainWindow();
trytocallit.MyMethod();
}
}
}
这当然不行。感谢您的帮助!
好吧,这样做听起来不对,但是如果您必须在内存中获取对象而不是创建一个新对象..
但是这个剂量听起来不错..告诉我们你为什么要这样做,以便我们可以提出更好的方法
--- 只是为了让您的案例奏效.. 这样做..
主要window --
public static MainWindow Instance { get; private set; }
static MainWindow()
{
Instance = new MainWindow();
}
private MainWindow()
{
InitializeComponent();
}
在 app.xaml 中删除 StartupUri="MainWindow.xaml"
public App()
{
Startup += App_Startup;
}
void App_Startup(object sender, StartupEventArgs e)
{
TestApp.MainWindow.Instance.Show();
}
现在您可以在 Page 中访问静态实例 ... 调用方法
您可以做几件不同的事情。你可以实现类似 , which is similar to the Singleton pattern.
的东西
另一种选择是使用 dependency injection 在创建 Page
class 时提供 MainWindow
的一个实例。
public class Page : Page
{
private MainWindow MainWindow;
public Page(MainWindow mainWindow)
{
InitializeComponent();
this.MainWindow = mainWindow;
// Other constructor stuff
}
// Other methods, event handlers, etc.
}
通常使用依赖注入,我们依赖抽象而不是具体实现(以减少耦合)。
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();
}
}
考虑利用带参数的消息传递在对象之间传递数据。
您可以使用 EventAggregator or MessageBus.
我们的想法是让您的用户控件订阅他们想要响应的事件。
注意:
我用视图模型来做这个。
但是,我认为将此代码添加到用户控件时会产生代码味道,无论使用它们的应用程序如何,都应具有一般用途。
我使用 发布订阅模式 来处理复杂的 class-依赖关系:
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();
});
}
}
您可以利用 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
}
}
订阅
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);
}
}
作为替代和快速的解决方案,您可以使用以下代码
用法:
MainWindow mainWindow = GetMainWindow();
方法:
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;
}
抱歉回复晚了,我有一个简单的解决方案。
- 在 Page.xaml 中创建 public 字符串变量。
- 如果您点击页面上的按钮,变量将获得一些值。
- 在 MainWindow 上创建新的背景 theard 并运行一个无限循环 while (true) {..}
- 值public字符串变量一次又一次的循环控制... with Thread.Sleep(10);
- 如果它找到一个在 MainWindow 中执行某些操作的值
它对我来说也很简单:)
我在同一个命名空间中有 MainWindow.xaml 和另一个 Page.xaml
MainWindow 上有文本块和框架。
MainWindow 上的框架显示 Page.xaml,该页面上有一个按钮。
我想用那个按钮在 MainWindow 中调用非静态方法,但我不知道如何:(
例如:
MainWindow.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
namespace wpfapp
{
public partial class Page : Page
{
public Page()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MainWindow trytocallit = new MainWindow();
trytocallit.MyMethod();
}
}
}
这当然不行。感谢您的帮助!
好吧,这样做听起来不对,但是如果您必须在内存中获取对象而不是创建一个新对象..
但是这个剂量听起来不错..告诉我们你为什么要这样做,以便我们可以提出更好的方法
--- 只是为了让您的案例奏效.. 这样做..
主要window --
public static MainWindow Instance { get; private set; }
static MainWindow()
{
Instance = new MainWindow();
}
private MainWindow()
{
InitializeComponent();
}
在 app.xaml 中删除 StartupUri="MainWindow.xaml"
public App()
{
Startup += App_Startup;
}
void App_Startup(object sender, StartupEventArgs e)
{
TestApp.MainWindow.Instance.Show();
}
现在您可以在 Page 中访问静态实例 ... 调用方法
您可以做几件不同的事情。你可以实现类似
另一种选择是使用 dependency injection 在创建 Page
class 时提供 MainWindow
的一个实例。
public class Page : Page
{
private MainWindow MainWindow;
public Page(MainWindow mainWindow)
{
InitializeComponent();
this.MainWindow = mainWindow;
// Other constructor stuff
}
// Other methods, event handlers, etc.
}
通常使用依赖注入,我们依赖抽象而不是具体实现(以减少耦合)。
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();
}
}
考虑利用带参数的消息传递在对象之间传递数据。
您可以使用 EventAggregator or MessageBus.
我们的想法是让您的用户控件订阅他们想要响应的事件。
注意:
我用视图模型来做这个。 但是,我认为将此代码添加到用户控件时会产生代码味道,无论使用它们的应用程序如何,都应具有一般用途。
我使用 发布订阅模式 来处理复杂的 class-依赖关系:
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();
});
}
}
您可以利用 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
}
}
订阅
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);
}
}
作为替代和快速的解决方案,您可以使用以下代码
用法:
MainWindow mainWindow = GetMainWindow();
方法:
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;
}
抱歉回复晚了,我有一个简单的解决方案。
- 在 Page.xaml 中创建 public 字符串变量。
- 如果您点击页面上的按钮,变量将获得一些值。
- 在 MainWindow 上创建新的背景 theard 并运行一个无限循环 while (true) {..}
- 值public字符串变量一次又一次的循环控制... with Thread.Sleep(10);
- 如果它找到一个在 MainWindow 中执行某些操作的值
它对我来说也很简单:)