UserControl 中整个对象的 WPF 数据绑定

问题描述 投票:0回答:1

我有一个关于数据绑定的问题。 我使用 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 上的值,而人的年龄是(并且保持)为空。

我知道通过仅将属性绑定到用户界面是可能的,但由于这只是一个示例,实际上我的对象中有更多属性,这将是一团糟,我更愿意以某种方式“传递”或将整个对象绑定到用户控件。 有谁知道我如何检测对象属性的变化或者如何解决我的问题?

非常感谢您的帮助!!

.net wpf data-binding user-controls
1个回答
0
投票

您实际上并不需要 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}" />
© www.soinside.com 2019 - 2024. All rights reserved.