简体   繁体   English

将 DependencyProperty 转发到包含在用户控件中的控件

[英]forward DependencyProperty to control contained in User Control

I'm trying to make a user control that has a few DependencyProperties which are forward to child controls in the user control.我正在尝试制作一个具有一些DependencyProperties的用户控件,这些DependencyProperties转发给用户控件中的子控件。 After a few trys I got this to work.经过几次尝试,我得到了这个工作。 For testing a made a small example.为测试做了一个小例子。

In the example I have a user control named Ctrl that just contains a TextBox and exposes the Text property of the TextBox .在这个例子中我有一个名为的用户控件Ctrl只包含一个TextBox ,并公开Text中的属性TextBox This control is used in a window which contains a TextBox and my custom Ctrl which are bound to the same property.此控件用于包含绑定到同一属性的TextBox和我的自定义Ctrl的窗口中。

user control用户控制

XAML XAML

<UserControl x:Class="trying.Ctrl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="{Binding RelativeSource={RelativeSource self}}"
    Height="Auto" Width="Auto">
    <TextBox Text="{Binding MyText}" />
</UserControl>

Code behind背后的代码

using System.Windows;
using System.Windows.Controls;

namespace trying
{
    public partial class Ctrl : UserControl
    {
        public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register(
            "MyText",
            typeof( string ),
            typeof( UserControl ),
            new FrameworkPropertyMetadata( default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
        public string MyText
        {
            get { return (string)GetValue( MyTextProperty ); }
            set { SetValue( MyTextProperty, value ); }
        }

        public Ctrl()
        {
            InitializeComponent();
        }
    }
}

window窗户

XAML XAML

<Window x:Class="trying.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cc="clr-namespace:trying"
    DataContext="{Binding RelativeSource={RelativeSource self}}"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBox Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding DisplayText}" />
        <cc:Ctrl Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" MyText="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DisplayText}" />
    </Grid>
</Window>

code behind背后的代码

using System.Windows;
using System.ComponentModel;

namespace trying
{
    public partial class Window1 : Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged( string propertyName )
        {
            if( PropertyChanged != null )
                PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
        }

        private string m_displayText = "asdf";
        public string DisplayText
        {
            get { return m_displayText; }
            set
            {
                m_displayText = value;
                NotifyPropertyChanged( "DisplayText" );
            }
        }

        public Window1()
        {
            InitializeComponent();
        }
    }
}

problem问题

How I posted the code it works.我如何发布它的工作代码。 My question is now: What have I done wrong that I have to use the binding我现在的问题是:我做错了什么,我必须使用绑定

 MyText="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}

When binding the MyText property of Ctrl and can not just the simple binding like I use when binding the original TextBox ?当绑定CtrlMyText属性时,不能像我在绑定原始TextBox时使用的那样简单绑定?

If I don't bind this way it won't work, and I get the warning如果我不以这种方式绑定它将无法工作,我会收到警告

  System.Windows.Data Error: 39 : BindingExpression path error: 'DisplayText' property
  not found on 'object' ''Ctrl' (Name='')'. BindingExpression:Path=DisplayText; 
  DataItem='Ctrl' (Name=''); target element is 'Ctrl' (Name=''); target property
  is 'MyText' (type 'String')

What do I have to change that binding is possible like with the original TextBox ?我必须如何更改与原始TextBox一样的绑定?

during execution.在执行过程中。

The UserControl 's DataContext is pointing to itself, so any binding on an instance of the control will be looking at the Ctrl instance rather than the inherited DataContext . UserControlDataContext指向自身,因此控件实例上的任何绑定都将查看Ctrl实例而不是继承的DataContext

Try setting the DataContext further down the tree:尝试在树的更下方设置DataContext

<UserControl 
   x:Class="trying.Ctrl" x:Name="root"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Height="Auto" Width="Auto"
>
   <TextBox 
      DataContext="{Binding ElementName=root}"
      Text="{Binding MyText}" 
   />
</UserControl>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM