1

我创建了一个名为 SimpleText 的 UserControls,并在我的 MainWindow.xaml 中引用了它。我的 SimpleText 中唯一的东西是一个 TextBox(称为 tbox)。在我的 MainWindow 中有另一个 TextBox(称为 tbox2)。我想要实现的是在这两个文本框之间进行双向绑定。

我在 stackoverflow 中读到这里要在内部更改某些内容,您必须在 UserControls 的代码中声明一个属性(如果不需要,请纠正我):

 public string MyText
        {
            get { return tboxUser.Text; }
            set { tboxUser.Text = value; }
        }

然后我可以从 MainWindow.xaml 访问 MyText 但只能给它“静态”值:

Window x:Class="WpfApplication11.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication11"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <!-- <local:SimpleText MyText="Hello"/>  Works !-->
        <local:SimpleText MyText="{Binding Text, ElementName=tbox2}"/> <!--Does not work-->
        <TextBox x:Name="tbox2" Margin="0,200,0,0"  Text="Text Box 2" />
    </Grid>
</Window>

它给了我一个错误说:

不能在“SimpleText”类型的“MyText”属性上设置“绑定”。只能在 DependencyObject 的 DependencyProperty 上设置“绑定”。

但遗憾的是,我在这里非常新手,我不知道如何使 MyText 成为 DependencyProperty。谢谢。

4

1 回答 1

2
ripped from http://www.andrewdenhertog.com/c/create-dependencyproperty-dependencyobject-5-minutes/

public int Age
    {
        get { return (int)GetValue(AgeProperty); } //do NOT modify anything in here
        set { SetValue(AgeProperty, value); } //...or here
    }

    // Using a DependencyProperty as the backing store for Age.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty AgeProperty =
        DependencyProperty.Register(
        "Age",  //Must be the same name as the property created above
        typeof(int), //Must be the same type as the property created above
        typeof(Person), //Must be the same as the owner class
        new UIPropertyMetadata(
            0,  //default value, must be of the same type as the property
            new PropertyChangedCallback((s, e) =>  //A callback that gets executed when the property changed
            {
                var source = s as Person;
                s.DOB_Year = DateTime.Now.Year - s.Age; 
            })));

对于您的情况,它将类似于以下内容(请注意 frameworkpropertymetadataoptions.bindstwowaybydefault)。我实际上并没有对此进行测试,所以不确定语法是否正确,但它的总体思路

public string MyText
{
    get { return (string)GetValue(MyTextProperty); } //do NOT modify anything in here
    set { SetValue(MyTextProperty, value); }
}

public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register("MyText", typeof(string), typeof(SimpleText), new FrameworkPropertyMetadata(null,
                              FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                              MyTextPropertyChangedCallback));

private static void MyTextPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var source = d as SimpleText;
    source.MyText = e.NewValue.ToString();
}

更新

我尝试使用这个简单的示例重新创建并注意到您在评论中的相同内容。 本文提供了一些更深入的解释。在文章的底部,它描述了用户控件的数据上下文是如何从父级继承的。您不会在编译时看到错误,但是如果您打开 wpf tracking for data binding,您会在输出控制台中注意到数据绑定错误。修复方法是调整用户控件内的数据上下文,这可以通过多种方式完成,但最简单的可能是在构造函数中,在 xaml 中的顶级 UI 元素(网格或堆栈面板或其他)上设置数据上下文) 对自己。

public SimpleText()
{
    InitializeComponent();
    grid.DataContext = this;
}
于 2013-05-26T03:10:05.260 回答