C# 绑定UserControls的元素
我创建了一个名为SimpleText的UserControls,并在MainWindow.xaml中引用了它。我的SimpleText中只有一个文本框(称为tbox)。在我的主窗口中有另一个文本框(称为tbox2)。我想要实现的是在这两个文本框之间有一个双向绑定 我在stackoverflow中读到,要在内部更改某些内容,必须在UserControls的代码中声明一个属性(如果不需要,请更正我): 然后我可以从MainWindow.xaml访问MyText,但只能给它“静态”值:C# 绑定UserControls的元素,c#,wpf,binding,user-controls,C#,Wpf,Binding,User Controls,我创建了一个名为SimpleText的UserControls,并在MainWindow.xaml中引用了它。我的SimpleText中只有一个文本框(称为tbox)。在我的主窗口中有另一个文本框(称为tbox2)。我想要实现的是在这两个文本框之间有一个双向绑定 我在stackoverflow中读到,要在内部更改某些内容,必须在UserControls的代码中声明一个属性(如果不需要,请更正我): 然后我可以从MainWindow.xaml访问MyText,但只能给它“静态”值: windowx
windowx:Class=“WpfApplication11.MainWindow”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local=“clr命名空间:WpfApplication11”
Title=“MainWindow”Height=“350”Width=“525”>
这样说给了我一个错误:
无法在“SimpleText”类型的“MyText”属性上设置“Binding”。只能对DependencyObject的DependencyProperty设置“绑定”
但遗憾的是,我在这里非常新手,我不知道如何使我的文本成为一个独立的属性。谢谢
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.bindstwoway默认值)。我并没有实际测试这个,所以不确定语法是否正确,但这是一般的想法
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();
}
更新
我试着用这个简单的例子重新创建,并注意到了你在评论中提到的同样的事情。提供了一些更深入的解释。在文章的底部,它描述了如何从父控件继承用户控件的数据上下文。您在编译时不会看到错误,但如果您这样做,您会在输出控制台中注意到数据绑定错误。修复方法是调整用户控件内的数据上下文,这可以通过两种方法完成,但最简单的方法可能是在构造函数中,将xaml(网格或堆栈面板或其他)中顶级UI元素上的数据上下文设置为自身
public SimpleText()
{
InitializeComponent();
grid.DataContext = this;
}
我已经试过了,但是尽管编译器没有抛出错误,绑定还是不起作用。ThanksI最终可以通过添加DataContext引用和我缺少的另一件事来设置绑定:将UserControl XAML textbox中的绑定到MyText属性。现在,我有一个奇怪的行为:如果我在主窗口文本框(tbox2)中写入,它会自动更新,但如果我在用户控制文本框(tbox)中写入,我必须单击另一个文本框才能进行更改。这与INotifyPropertyChanged有关吗?好的,这是我最后一个问题的解决方案:Text=“{Binding ElementName=miControl,Path=MyText,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}”。我认为默认的方法是在控件失去焦点时进行更新(这就是为什么当我单击另一个文本框时,值被更新)。是的。默认行为是在焦点更改时更新。你说得对。
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();
}
public SimpleText()
{
InitializeComponent();
grid.DataContext = this;
}