Wpf 绑定到兄弟姐妹';s子元素
我正在处理一个用户控件(名为DiagramControl),但遇到了一个问题。UserControl的代码如下所示:Wpf 绑定到兄弟姐妹';s子元素,wpf,binding,wpf-controls,siblings,Wpf,Binding,Wpf Controls,Siblings,我正在处理一个用户控件(名为DiagramControl),但遇到了一个问题。UserControl的代码如下所示: <UserControl> <Border> <Grid> <ScrollViewer x:Name="DesignerScrollViewer" ... /> ... <s:ZoomBox x:Name="zoomBox"
<UserControl>
<Border>
<Grid>
<ScrollViewer x:Name="DesignerScrollViewer" ... />
...
<s:ZoomBox x:Name="zoomBox"
ScrollViewer="{Binding ElementName=DesignerScrollViewer}"/>
</Grid>
</Border>
</UserControl>
既然ScrollViewer DP有了更新源,我就可以使用DiagramControl从窗口绑定到它。希望这对将来的人有所帮助。首先,你不应该将UI控件放入视图模型属性中(没有很好的理由-让视图模型保存所有信息并绑定到这些属性中)-你的结构(视图模型)太过“复杂”,导致越来越多的黑客行为-这是不可能的:) 如果我没弄错,你要找的是 您的
DesignerScrollViewer
只是一个“子控件”,绑定标记扩展不知道它
如果你想要那样的东西,那就做一个
DesignerScrollViewerProperty
上的UserControl
并将其放入
路径(保留ElementName
part)。那可能只是一种财产
(您需要INotifyPropertyChanged
和引发事件)
或者有点不同,比如
在你的窗口某处:
<my:ZoomBox DataContext="{Binding ElementName=diagramControl, Path=.}"></my:ZoomBox>
<my:DiagramControl x:Name="diagramControl"></my:DiagramControl>
…您可以绑定到DP(而不是DataContext
)。并将您想要的任何动作(例如放大/缩小)放在屏幕上,而不是向上/向下
这仍然是不合适的,为了使它正常运行-您应该将图表和缩放框绑定到同一视图模型(跳过直接绑定到用户控件-但通过视图模型间接“通信”)-但这会使问题变得复杂,因为您需要一些事件来处理命令,要双向绑定,使值来回循环等。首先,您不应该将UI控件放入视图模型属性(没有很好的理由-使视图模型保存所有信息并绑定到该属性)-您的结构(视图模型)太“涉入”并导致越来越多的黑客——这是不可能的:) 如果我没弄错,你要找的是 您的
DesignerScrollViewer
只是一个“子控件”,绑定标记扩展不知道它
如果你想要那样的东西,那就做一个
DesignerScrollViewerProperty
上的UserControl
并将其放入
路径(保留ElementName
part)。那可能只是一种财产
(您需要INotifyPropertyChanged
和引发事件)
或者有点不同,比如
在你的窗口某处:
<my:ZoomBox DataContext="{Binding ElementName=diagramControl, Path=.}"></my:ZoomBox>
<my:DiagramControl x:Name="diagramControl"></my:DiagramControl>
…您可以绑定到DP(而不是DataContext
)。并将您想要的任何动作(例如放大/缩小)放在屏幕上,而不是向上/向下
这仍然是不合适的,为了使它正常运行-您应该将图表和缩放框绑定到同一视图模型(跳过直接绑定到用户控件-但通过视图模型间接“通信”)-但这会使问题变得复杂,因为您需要一些事件来处理命令,并对值进行双向绑定,以便来回循环等。感谢@NSGaga这是我第一次尝试的方法,就像我为ZoomBox设置ScrollViewer DP时所做的那样。我不知道该把它和什么绑在一起。我已经弄明白了,请看我的更新谢谢:)哪个更新:)-我不认为你理解它(或者我错过了它),我回答了你的问题-这是你需要的另一个属性-再看一次,了解一下整个情况-如果有任何问题,请告诉我。教授兄弟刚刚添加了更新。我最大的问题是弄清楚如何将ScrollViewer DP绑定到DesignerScrollViewer,但后来我意识到我只需要将它设置为DesignerScrollViewer\u LayoutUpdated之类的-只需要一个DP(在ZoomBox中),或者一个属性是绑定的“目标”-另一个只是需要INotifyPropertyChanged-只是为了让您理解事情-很高兴它成功了。此外,如果您像我一样使用
DataContext
(这就是原因)-如果您ZoomBox
仅用于该ScrollViewer,那么您可以不使用DP。另一方面,如果你想同时缩放多个控件,那么最好使用两个用户控件都绑定的“不可知视图模型”——如果你需要的话,你知道去哪里找(你不能用缠绕控件来做),谢谢@NSGaga,这是我第一次尝试的方法,正如我在为ZoomBox设置ScrollViewer DP时所做的那样。我不知道该把它和什么绑在一起。我已经弄明白了,请看我的更新谢谢:)哪个更新:)-我不认为你理解它(或者我错过了它),我回答了你的问题-这是你需要的另一个属性-再看一次,了解一下整个情况-如果有任何问题,请告诉我。教授兄弟刚刚添加了更新。我最大的问题是弄清楚如何将ScrollViewer DP绑定到DesignerScrollViewer,但后来我意识到我只需要将它设置为DesignerScrollViewer\u LayoutUpdated之类的-只需要一个DP(在ZoomBox中),或者一个属性是绑定的“目标”-另一个只是需要INotifyPropertyChanged-只是为了让您理解事情-很高兴它成功了。此外,如果您像我一样使用DataContext
(这就是原因)-如果您ZoomBox
仅用于该ScrollViewer,那么您可以不使用DP。另一方面,如果您想同时缩放多个控件,那么最好使用两个用户控件都绑定到的“不可知视图模型”——如果需要,您知道在哪里查找(使用缠绕控件无法做到这一点)
<my:ZoomBox DataContext="{Binding ElementName=diagramControl, Path=.}"></my:ZoomBox>
<my:DiagramControl x:Name="diagramControl"></my:DiagramControl>
<UserControl x:Class="YourApp.ZoomBox" ...="">
<StackPanel>
<Button x:Name="GoUp" Command="{Binding UpCommand}" Content="Go Up" IsDefault="False" />
<Button x:Name="GoDown" Command="{Binding DownCommand}" Content="Go Down" IsDefault="False" />
</StackPanel>
</UserControl>
<UserControl x:Class="YourApp.DiagramControl" ...="">
<Grid>
<ScrollViewer x:Name="_scrollViewer" >
...
</ScrollViewer>
</Grid>
</UserControl>
public partial class DiagramControl : UserControl, INotifyPropertyChanged
{
RelayCommand _upCommand;
RelayCommand _downCommand;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) { this.PropertyChanged.Raise(this, new PropertyChangedEventArgs(propertyName)); }
public DiagramControl()
{
InitializeComponent();
}
public RelayCommand UpCommand
{
get
{
return _upCommand ?? (_upCommand = new RelayCommand(
param =>
{
_scrollViewer.LineUp();
},
param => true));
}
}
public RelayCommand DownCommand
{
get
{
return _downCommand ?? (_downCommand = new RelayCommand(
param =>
{
_scrollViewer.LineDown();
},
param => true));
}
}
}