我有一个关于数据绑定的问题。 我使用 ViewModel 创建了一个 WPF 应用程序。在这个 viewModel 中,我有一个来自我编写的类的对象,其中包含多个属性。我想创建一个带有一些标签的用户控件,这些标签显示对象的属性值。然后我想将此 UserControl 添加到主窗口,并且我想将整个对象传递到此 UserControl,我想将标签内容绑定到对象的不同属性。
为了让这一点更清楚,我在这里写了一个小例子。
我的班级叫做Person:
public class Person
{
public int[] data;
public string name;
public int age;
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
}
然后我使用以下两个标签创建了用户控件 UC_Person:
<Grid>
<StackPanel>
<Label Name="label1" Background="Yellow"></Label>
<Label Name="label2" Background="Red"></Label>
</StackPanel>
</Grid>
在 UC_Person.cs 代码中,我添加了以下内容,我想在其中“存储”一个 Person 对象。为了向您展示问题,我还添加了一个额外的字符串 LabelContent,因为我的数据绑定正在工作。
public Person person
{
get { return (Person)GetValue(PersonProperty); }
set { SetValue(PersonProperty, value); }
}
public static readonly DependencyProperty PersonProperty =
DependencyProperty.Register("person", typeof(Person), typeof(UC_Person),// null);
new PropertyMetadata(new PropertyChangedCallback(UC_Person.PersonPropertyChanged)));
public string LabelContent
{
get { return (string)GetValue(LabelContentProperty); }
set { SetValue(LabelContentProperty, value); }
}
public static readonly DependencyProperty LabelContentProperty =
DependencyProperty.Register("LabelContent", typeof(string), typeof(UC_Person),// null);
new PropertyMetadata(new PropertyChangedCallback(UC_Person.LabelContentChanged)));
private static void LabelContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
UC_Person person = (UC_Person)d;
person.label1.Content = person.LabelContent;
Console.WriteLine("label changed");
}
private static void PersonPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Console.WriteLine("Person changed");
}
在 MainWindowViewModel 中,我还使用 get 和 set 以及 PropertyChanged 的调用创建了两个对象 person 和 labelContent。
private Person _person = new Person("Peter", 20);
public Person person
{
get { return _person; }
set
{
_person = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("person"));
}
}
private string _labelContent = "";
public string labelContent
{
get { return _labelContent; }
set
{
_labelContent = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("labelContent"));
}
}
现在我将用户控件添加到我的 MainWindow.xaml 中,我尝试将 ViewModel 中的人绑定到用户控件 UC_Person。
<local:UC_Person person="{Binding person}" LabelContent="{Binding labelContent}" HorizontalAlignment="Left" Height="62" Margin="73,156,0,0" VerticalAlignment="Top" Width="143"/>
目标是,例如,我可以在用户控件的标签上显示人的年龄,并且它应该绑定到人年龄的实时数据。我认为我遇到的问题是改变人的年龄(例如,通过按主窗口上的按钮,使 person.age++ ;不使用人的设置器,因为对象仍然保持不变,但只是其属性发生了变化。所以我猜我的 propertychanged 不会触发,并且带有“Console.WriteLine("Personchanged");”的代码行永远不会运行。
所以我在主窗口中添加了一个按钮,方法是更改标签内容和模型的人物年龄。
private void Button_Click(object sender, RoutedEventArgs e)
{
this._model.person.age++;
this._model.labelContent = cnt + "something";
cnt++;
}
但是,标签正在完美地改变其在 UI 上的值,而人的年龄是(并且保持)为空。
我知道通过仅将属性绑定到用户界面是可能的,但由于这只是一个示例,实际上我的对象中有更多属性,这将是一团糟,我更愿意以某种方式“传递”或将整个对象绑定到用户控件。 有谁知道我如何检测对象属性的变化或者如何解决我的问题?
非常感谢您的帮助!!
您实际上并不需要 UserControl 中的
person
属性
将 Person 类的字段转换为属性(在下面的代码中为只读),以便您可以将它们与数据绑定一起使用。
public class Person
{
public string Name { get; }
public int Age { get; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
在 UserControl 的 XAML 中,将 UI 元素绑定到 Person 属性,例如
<TextBlock Text="{Binding Name}"/>
要使该绑定起作用,请将 Person 对象分配给
DataContext
属性:
<local:UC_Person DataContext="{Binding person}" />