【发布时间】:2017-08-25 07:55:25
【问题描述】:
在具有 MVVM 模式的 WPF 应用程序中,我有一个按钮。内容与主窗口中的属性绑定:
<Button x:Name="button" Content="{Binding Stamp, Mode=TwoWay }"/>
我试图弄清楚绑定 relativesource 是如何工作的。我需要在 UserControl 中获取“Stamp”内容
<Button x:Name="button" Content="{Binding DataContext.MainWindowViewModel.Stamp, RelativeSource={RelativeSource FindAncestor , AncestorType={x:Type Button }}}"/>
但它不起作用。
MainWindow 的完整 XAML 代码是:
<Window x:Class=" WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:WpfApplication4.WpfApplication4"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType="{x:Type local:uc1VM}">
<local:UserControl1 />
</DataTemplate>
<DataTemplate DataType="{x:Type local:uc2VM}">
<local:UserControl2/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel>
<TextBox x:Name="txbFieldDescription" VerticalContentAlignment="Center" MinWidth=" 90" Text="{Binding FieldDescription, Mode=TwoWay}" HorizontalAlignment="Stretch" DockPanel.Dock="Top" Height=" 22">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus" >
<i:InvokeCommandAction Command="{Binding NavigateCommand}" CommandParameter="{x:Type local:uc1VM}" />
</i:EventTrigger>
<i:EventTrigger EventName="LostFocus" >
<i:InvokeCommandAction Command="{Binding NavigateCommand}" CommandParameter="{x:Type local:uc2VM}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<Button x:Name="button" Content="{Binding Stamp, Mode=TwoWay }"/>
</StackPanel>
<ContentControl Grid.Column="1" Content="{Binding UCVM}" />
</Grid>
这也是MainViewModel的代码:
Namespace WpfApplication4
Public Class MainWindowViewModel
' Implements INotifyPropertyChanged
Inherits ViewModelBase
Private m_ucVM As Object
Public Property UCVM() As Object
Get
Return m_ucVM
End Get
Set(ByVal value As Object)
m_ucVM = value
OnPropertyChanged("UCVM")
End Set
End Property
Private mStamp As String
Public Property Stamp() As String
Get
Return mStamp
End Get
Set(ByVal value As String)
mStamp = value
OnPropertyChanged("Stamp")
End Set
End Property
Private _navigateCommand As RelayCommand(Of Type)
Public ReadOnly Property NavigateCommand() As RelayCommand(Of Type)
Get
If _navigateCommand IsNot Nothing Then
Return _navigateCommand
Else
Return New RelayCommand(Of Type)(Sub(newVMType)
UCVM = Nothing
If newVMType.Name = "uc1VM" Then
Stamp = "Ciao vecchio"
Else
Stamp = "Ciao nuovo"
End If
UCVM = Activator.CreateInstance(newVMType)
End Sub)
End If
End Get
End Property
Public Sub New()
Stamp = "Ciao Primo"
End Sub
End Class
结束命名空间
两者的 UsersControls XAML 相同:
<UserControl x:Class="WpfApplication4.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication4"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid >
<Button x:Name="button" Height=" 20" Width=" 120" Content="{Binding DataContext.Stamp, RelativeSource={RelativeSource TemplatedParent }}"/>
</Grid>
我简化了所有内容以便更好地理解。 我上传了here 一个示例项目。
【问题讨论】:
-
Stamp属性到底在哪里?您的Button位于哪里(在集合的ItemTemplate的一部分的主窗口中)? -
它基于MVVM模式,所以Stam属性在MainWindow的VM中。有两个按钮,一个在主窗口中,另一个在用户控件中。我需要从主窗口上的按钮中获取内容并将其放入用户控件的内容中。
-
我猜你在
Window中使用了UserControl。您是否尝试过将UserControl的DataContext设置为Window之一,并像在Window中那样绑定Button的Content? -
View 和 Usercontrol 都将 datacontext 设置为它们的 VM(MainViewVM 和 UserControlVM)。
-
你有没有在
UserControl中尝试过没有RelativeSource?
标签: wpf xaml mvvm user-controls