在WPF中将Control2的DP绑定到Control1的DP

时间:2018-10-11 08:59:14

标签: c# wpf data-binding user-controls dependency-properties

我有两个简单的UserControl。两者都有一个名为Value的依赖项属性。现在我在MainWindow中使用控件,并尝试将一个值绑定到另一个值!不幸的是,它仅在第一次使用时有效,而在我更改control1中的“值”后不会更新。

Control1:

<UserControl x:Class="ControlBining.Control1"
             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"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <TextBox Text="{Binding Value, RelativeSource={RelativeSource AncestorType=UserControl}}" Width="100"/>
    </Grid>
</UserControl>

  public static readonly DependencyProperty ValueProperty =
     DependencyProperty.Register(
        "Value", typeof(string),
        typeof(Control1)
     );

  public string Value
  {
     get => (string)GetValue(ValueProperty);
     set => SetValue(ValueProperty, value);
  }

Control2:

<UserControl x:Class="ControlBining.Control2"
             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:ControlBining"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <TextBlock Text="{Binding Value, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
    </Grid>
</UserControl>

  public static readonly DependencyProperty ValueProperty =
     DependencyProperty.Register(
        "Value", typeof(string),
        typeof(Control2)
     );

  public string Value
  {
     get => (string)GetValue(ValueProperty);
     set => SetValue(ValueProperty, value);
  }

MainWindow:

<Window x:Class="ControlBining.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:local="clr-namespace:ControlBining"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <local:Control1 Width="100" x:Name="Control1" Value="10"/>
        <local:Control2 Width="100" Value="{Binding ElementName=Control1, Path=Value}"/>
    </StackPanel>
</Window>

1 个答案:

答案 0 :(得分:1)

UserControl不应设置自己的DataContext,因为这样做会破坏其依赖属性的任何基于DataContext的绑定。而是在其XAML中使用RelativeSource绑定:

<UserControl ...>
    <Grid>
        <TextBox Text="{Binding Value,
                        RelativeSource={RelativeSource AncestorType=UserControl}}"/>
    </Grid>
</UserControl>

如果您要在输入文本框时更新Value属性,请同时进行以下设置:

<TextBox Text="{Binding Value,
                RelativeSource={RelativeSource AncestorType=UserControl},
                UpdateSourceTrigger=PropertyChanged}"/>

当您还想输入Control2时,请进行Value Binding TwoWay:

<local:Control2 Value="{Binding ElementName=Control1, Path=Value, Mode=TwoWay}"/>

或默认使Value属性绑定TwoWay:

public static readonly DependencyProperty ValueProperty =
    DependencyProperty.Register(
        nameof(Value), typeof(string), typeof(Control2),
        new FrameworkPropertyMetadata(
            null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));