WPF Button.Content绑定如何在usercontrol中使用父窗口中的RelativeSource

时间:2017-08-25 07:55:26

标签: wpf xaml mvvm user-controls

在具有MVVM模式的WPF应用程序中,我有一个button.Contenet与主窗口中的propety绑定:

 <Button x:Name="button" Content="{Binding Stamp, Mode=TwoWay }"/>

我试图找出绑定亲属的工作方式。我需要采取&#34; Stamp&#34; UserControl中的内容

 <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示例项目。

2 个答案:

答案 0 :(得分:0)

在您的示例中,AncestorType设置为x:Type Button。您应该搜索父视图的类型,因为您想要绑定到此类型的datacontext(viewmodel)。

<Button x:Name="button" Content="{Binding DataContext.Stamp, RelativeSource={RelativeSource FindAncestor , AncestorType={x:Type VIEW}}}"/>

修改

我下载了您的示例项目并将UserControl1.xaml更新为:

<UserControl x:Class="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:WpfApplication5"
             mc:Ignorable="d" >
    <Grid >
        <Button x:Name="button" HorizontalAlignment="Left"  VerticalAlignment="Top" Width="175" Height=" 22" Content="{Binding DataContext.Stamp, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow }}}"/>
    </Grid>
</UserControl>

通过此编辑,usercontrol的按钮显示正确的内容。

答案 1 :(得分:0)

试试这个:

<Button x:Name="button" Content="{Binding DataContext.Stamp, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>

它绑定到父窗口的Stamp的{​​{1}}属性。