简体   繁体   English

将WPF控件绑定到对象

[英]Binding a WPF control to an Object

I have an object called "Employee", as follows: 我有一个名为“ Employee”的对象,如下所示:

class Employee
{
    public string EmpName { get; set; }
    public string Surname { get; set; }

    public Employee(string Name, string Surname) : base()
    {
        this.EmpName = EmpName;
        this.Surname = Surname;
    }

    public Employee()
    {
    }
}

I also have this simple "EmployeeControl" here. 我在这里也有这个简单的“ EmployeeControl”。 Just two labels in a grid: 网格中只有两个标签:

<UserControl x:Class="LabelBindingTest.EmployeeCtrl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             Name="EmpCtrl"
             d:DesignHeight="120" d:DesignWidth="411">
    <Grid>
        <Label Content="{Binding ElementName=EmpCtrl, Path=EmpName}" Height="28" HorizontalAlignment="Left" Name="label1" VerticalAlignment="Top" Width="81" />
        <Label Content="{Binding ElementName=EmpCtrl, Path=Surname}" Height="28" HorizontalAlignment="Right" Name="label2" VerticalAlignment="Top" Width="81" />
    </Grid>
</UserControl>

(Edit) EmployeeControl codebehind: (编辑)EmployeeControl代码背后:

   public partial class EmployeeCtrl : UserControl
    {
        Employee thisEmployee = new Employee();

        public string EmpName
        {
            get
            {
                return thisEmployee.EmpName;
            }

            set
            {
                thisEmployee.EmpName = value;
            }
        }

        public string Surname
        {
            get
            {
                return thisEmployee.EmpName;
            }

            set
            {
                thisEmployee.EmpName = value;
            }
        }


        public EmployeeCtrl()
        {
            InitializeComponent();
        }
    }

Now, what I'm trying to do is add "EmployeeControl"s to my window and bind them to Employee objects. 现在,我想做的是在窗口中添加“ EmployeeControl”并将其绑定到Employee对象。 Here's my "window" code: 这是我的“窗口”代码:

<Window x:Class="LabelBindingTest.MainWindow"
        Name="myWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:LabelBindingTest">
    <Grid>
        <my:EmployeeCtrl EmpName="Daniel" Surname="Hammond" HorizontalAlignment="Left" Margin="23,26,0,0" x:Name="employeeCtrl1" VerticalAlignment="Top" Height="97" Width="429" />
    </Grid>
</Window>

I've tried a variety of things but I just can't get it to work. 我已经尝试了多种方法,但是我无法使其正常工作。 It compiles just fine but the label is empty. 它可以正常编译,但标签为空。 I just want to attach my "Employee" object to the "EmployeeCtrl" control. 我只想将我的“ Employee”对象附加到“ EmployeeCtrl”控件。 Any ideas on how I go around this? 关于如何解决这个问题有什么想法吗? I've read a lot about binding today and I'm still scratching my head. 我今天读了很多关于装订的文章,但仍在挠头。 I'm not sure if I need to implement INotifyPropertyChanged as I only set the employee names before runtime for now. 我不确定是否需要实现INotifyPropertyChanged,因为我现在仅在运行时之前设置员工姓名。

(Edit): I've downloaded Caliburn.Micro and used the same code in the last answer. (编辑):我已经下载了Caliburn.Micro,并在最后一个答案中使用了相同的代码。 Same result, empty window. 结果相同,窗口为空。

Here's the whole project. 这是整个项目。 All of it's code should be pasted in this question, though. 不过,所有代码都应粘贴在此问题中。 This is just for convenience sake. 这只是为了方便起见。

http://www.mediafire.com/?gux3573rz64mupe http://www.mediafire.com/?gux3573rz64mupe

Ok, firstly I would strongly recommend considering MVVM as your application gets more complicated, and use an MVVM framework if you're using MVVM . 好的,首先,我强烈建议您考虑MVVM,因为您的应用程序变得越来越复杂, 如果您使用的是MVVM ,请使用MVVM框架 I would recommend Caliburn.Micro which makes view composition like you're doing much much easier. 我建议使用Caliburn.Micro ,它使您的视图合成变得容易得多。 There are other MVVM frameworks available, so evaluate them all. 还有其他可用的MVVM框架,因此请对其进行评估。

For your issue, the problem is that your user control doesn't implement its properties as dependency properties. 对于您的问题,问题在于您的用户控件未将其属性实现为依赖项属性。 In the XAML, you're setting the EmpName and Surname properties of the user control, but the UI doesn't know that their values have changed after the user control is constructed, and therefore doesn't update itself. 在XAML中,您正在设置用户控件的EmpNameSurname属性,但是UI在构建用户控件后不知道它们的值已更改,因此不会自我更新。

You implement INotifyPropetyChanged on view models when using the MVVM pattern, and dependency properties on user controls. 使用MVVM模式时,可以在视图模型上实现INotifyPropetyChanged ,并在用户控件上实现依赖项属性 Both of these technqiues will notify the UI of a change and force it to update itself. 这两种技术都会将更改通知UI,并迫使其自行更新。

So for your user control you can do: 因此,对于您的用户控件,您可以执行以下操作:

public partial class EmployeeCtrl : UserControl
{
    public static readonly DependencyProperty EmpNameProperty = 
       DependencyProperty.Register("EmpName", typeof(string),
       typeof(EmployeeCtrl), new FrameworkPropertyMetadata(null));

    public static readonly DependencyProperty SurnameProperty = 
       DependencyProperty.Register("Surname", typeof(string),
       typeof(EmployeeCtrl), new FrameworkPropertyMetadata(null));

    public EmployeeCtrl()
    {
        this.InitializeComponent();
    } 

    public string EmpName
    {
       get { return (string)GetValue(EmpNameProperty); }
       set { SetValue(EmpNameProperty, value); }
    }

    public string Surname
    {
       get { return (string)GetValue(SurnameProperty); }
       set { SetValue(SurnameProperty, value); }
    }
}

You don't actually need your Employee class at all at this stage as you aren't using it, but ideally it should implement INotifyPropertyChanged if it's property values will change after construction and you have an instance of it is bound to the UI and you wish the UI to be updated. 实际上,在此阶段您根本不需要使用Employee类,因为您没有使用它,但是理想情况下,如果它的属性值在构造后会更改并且您有一个实例绑定到UI,并且它应该实现INotifyPropertyChanged希望更新用户界面。

you need to implement INotifyPropertyChanged on your EmployeeCtrl's EmpName and Surname property as the Label in this user control needs to be updated about the value change in this property value so that label can update its value. 您需要在EmployeeCtrl的EmpName和Surname属性上实现INotifyPropertyChanged,因为此用户控件中的Label需要更新此属性值的值更改,以便Label可以更新其值。 Hence you have to implement Notify change on EmpName and Surname property of the EmployeeCtrl or simply use dependency property for this two property. 因此,您必须对EmployeeCtrl的EmpName和Surname属性实施Notify更改,或仅对这两个属性使用依赖项属性。 Hope this helps!!! 希望这可以帮助!!!

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

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