如何从 WPF 中的另一个窗口绑定到 MainWindow 中的控件?
Posted
技术标签:
【中文标题】如何从 WPF 中的另一个窗口绑定到 MainWindow 中的控件?【英文标题】:How can I bind to a control in the MainWindow from another window in WPF? 【发布时间】:2013-01-06 01:09:21 【问题描述】:基本上,我的问题已经出现在标题中: 当我有如下 MainWindow 时:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:easycache"
xmlns:map="clr-namespace:MapControl;assembly=MapControl.WPF"
x:Class="easycache.MainWindow"
x:Name="MainWindow1"
Title="easycache"
Height="600"
Width="850">
<map:Map Grid.Column="2"
Grid.Row="1"
Name="map"
IsManipulationEnabled="True"
LightForeground="Black"
LightBackground="White"
DarkForeground="White"
DarkBackground="#FF3F3F3F"
Center="0.0,0.0"
ZoomLevel="0.0"
TileLayer="Binding Source=StaticResource TileLayersView, Path=CurrentItem" />
在我的窗口 2 中,我有:
<map:Map Name="map" IsManipulationEnabled="False"
LightForeground="Black" LightBackground="White" DarkForeground="White" DarkBackground="#FF3F3F3F"
Center="0.0,0.0" ZoomLevel="Binding ?????">
我想将 Window2 中地图的 ZoomLevel 绑定到我的 MainWindow 中地图的 ZoomLevel。我怎样才能做到这一点?
问候, 亚洛金
【问题讨论】:
如果你在做 MVVM,那么应该通信的是 ViewModel。如果你不是更简单。告诉我哪个,以便我可以给出正确的答案,问候 我同意 Hannish 的观点 - 有几种不同的方法可以做到这一点,具体取决于您的程序的架构方式。你在任何地方都使用 MVVM、ViewModels 和 Bindings 吗?还是只是直接事件和代码隐藏之类的? 感谢您的快速回答,我没有使用 MVVM!那你能给我举个例子吗? 怎么了? @Hannish,拜托,你能给我举个例子吗?我真的不知道该怎么办...... 【参考方案1】:在您的 MainWindow 代码隐藏中创建一个带有公共 get 访问器的公共属性,如下所示:
private double _mapZoom;
public double MapZoom //I assume that ZoomLevel is of type double, if not use the correct type
get return _mapZoom;
set _mapZoom = value; OnPropertyChanged("MapZoom");
您必须在您的 MainWindow 中实现 INotifyPropertyChanged 接口(到处都有一百万个示例,这里无需赘述)。
然后,将地图的 ZoomLevel 属性绑定到 MapZoom 属性,如下所示:
<map:Map Name="map" ZoomLevel="Binding RelativeSource=RelativeSource Self, Path=MapZoom, Mode=TwoWay"/>
为此,Window 的 DataContext 必须是 Window 本身,在 Window 的构造函数中需要一行:
public MainWindow()
InitializeComponent();
this.DataContext = this; //add this line
您需要一种方法让第二个窗口调用主窗口,因此您可以创建一个静态属性来返回主窗口中的当前实例:
private static MainWindow _instance;
public static MainWindow Instance
get
if (_instance == null)
_instance = new MainWindow();
else
_instance = this;
return _instance;
//you have to make sure to create ONE instance of MainWindow before getting this property, and not to create more instances elsewhere
现在您将在 MainWindow 中公开一个公共属性,该属性绑定到地图的缩放。
因此,在您的第二个窗口中创建一个指向该主窗口实例的属性:
public MainWindow Main get return MainWindow.Instance;
最后,您可以将第二张地图的缩放绑定到作为 Main 成员的公共属性 MapZoom:
<map:Map Name="map2" ZoomLevel="Binding RelativeSource=RelativeSource Self, Path=Main.MapZoom, Mode=TwoWay"">
在这个绑定中,“Main”是通过window2的public属性引用MainWindow实例(在window2中也设置this.DataContext = this;),并访问.MapZoom属性。
默认情况下,您在 XAML 中创建的所有对象都是私有的,因此您必须使用带有 get/set 访问器的公共属性显式公开它们,以使它们可以从外部访问。
让我知道这是否可行,我没有创建应用程序来测试代码。问候!
【讨论】:
感谢您的回答,但在等待回答时,我尝试了其他尝试来实现这一点:我现在创建了一个具有 currentzoom 属性的类,并两次绑定到该属性。 这是一个 WPF 反模式,应该避免:this.DataContext = this;相反,您应该查看 RelativeSource 在应用于绑定时的工作方式。 @user3690202 你应该详细说明为什么一个窗口不能是它自己的数据上下文,你应该做的是发布你自己的答案,展示如何按照你的方式去做。否定不是这里的方法。以上是关于如何从 WPF 中的另一个窗口绑定到 MainWindow 中的控件?的主要内容,如果未能解决你的问题,请参考以下文章
如何将listView的selectedItem值传递到wpf MVVM中的另一页