如何使用XAML在DataContext中设置一个类?

3

我有一个WPF表单和一个Users类(包含属性Id,Login和Name),在这个表单的类中,我获取了一个Users对象,并使用DataContextBinding将这些信息放入表单中。

我可以通过后台代码将这个Users对象放入我的Window.DataContext (this.DataContext = usersObject;),但我认为如果可以使用XAML实现可能会更好。

我在我的UserForm类中设置了一个属性(public Users usersObject {get; set;})。

我的表单是UserForm : Window

<Window DataContext="{What need I put here?">
    <Grid>
        <TextBlock Text="Id:"/>
        <TextBox Name="Id" Text="{Binding Path=Id}"/>

        <TextBlock Text="Login:"/>
        <TextBox Name="Login" Text="{Binding Path=Login}"/>

        <TextBlock Text="Name:"/>
        <TextBox Name="Name" Text="{Binding Path=Name}"/>
    </Grid>
</Window>

UserForm.xaml.cs

public class UserForm : Window
{
    public Users userObject { get; set; }

    public UserForm(Users user)
    {
        InitializeComponent();
        this.userObject = user;
    }
}

我的用户类

public class Users
{
    public int Id { get; set; }
    public string Login { get; set; }
    public string Name { get; set; }
}

如何在Window.DataContext中设置userObject,以便可以将其值放入TextBox中?


3
我认为"在背后编写代码"方法没问题(只需设置DataContext)。 - Federico Berasategui
是的,它可以工作,但我不想在代码后台设置DataContext。 - Lai32290
5个回答

5
请移除DataContext绑定,因为您没有明确进行MVVM模式。进行绑定没有任何意义。
在您的Window.xaml中:
<Window>
<Grid>
    <TextBlock Text="Id:"/>
    <TextBox Name="Id" Text="{Binding Path=Id}"/>

    <TextBlock Text="Login:"/>
    <TextBox Name="Login" Text="{Binding Path=Login}"/>

    <TextBlock Text="Name:"/>
    <TextBox Name="Name" Text="{Binding Path=Name}"/>
</Grid>

将以下代码添加到你的Behind the code Window.xaml.cs文件中。
    public class UserForm : Window
    {
        public Users userObject { get; set; }

        public UserForm(Users user)
        {
            InitializeComponent();
            this.DataContext = user;
        }
    }

如果你使用MVVM模式,你会做出类似这样的事情:
ViewModel.cs
    public class UserViewModel
    {
        private Users _model;
        public UserViewModel(Users model)
        {
            _model = model;
        }

        public int Id { get { return _model.Id; } }
        public string Login { get { return _model.Login; } set { _model.Login; } }
        public string Name { get { return _model.Name; } set { _model.Name; } }

    }

现在,ViewModel可以根据您的需求进行定制,您可以公开模型,将其注入构造函数或仅设置属性值(如果已公开)。 如果要将ViewModel中的任何值传播回用户界面,请不要忘记实现INotifyPropertyChanged。
View.xaml.cs public class UserForm : Window {
    public UserForm(Users user)
    {
        InitializeComponent();
        this.DataContext = new UserViewModel(user);
    }

View.xaml

你有两个选择,可以像我在代码后面所做的那样明确地设置DataContext,或者创建一个公共属性来返回UserViewModel。这两种方法都是一样的。

Model.cs

public class Users { //Whatever properties you need }

现在这是一个非常简单的MVVM模式示例。一旦你掌握了基础知识,就可以集成一些有用的框架来为您实现MVVM,例如Caliburn MicroMVVM Toolkit


使用XAML将DataContext绑定到userObject是不可能的吗?我是MVVM的初学者。 - Lai32290
这并不是不可能的,只是你没有做对。你需要一个ViewModel,其中包含User作为Model。让我更新答案。 - 123 456 789 0

5

我喜欢这篇文章,其中的第四个话题看起来像我正在寻找的内容,但我正在尝试。 - Lai32290

2
创建一个UserForm对象并分配数据上下文非常简单。
UserForm userFormView    = new UserForm ();
Users dataContextObject  = new Users();
userFormView.DataContext = dataContextObject;
userFormView.Show()          //you can also use showdialog. Thats up to you

最好您删除以下代码:

public Users userObject { get; set; }

public UserForm(Users user)
{
    InitializeComponent();
    this.userObject = user;
}

最好将视图和视图模型分开。看一下 MVVM 模式,这样会更加清晰易懂。


我在寻找类似的东西来解决与 OP 相似的问题。这太棒了,我发现它可以用于动态加载 TabItem,如果你将其 .Content 设置为来自此答案的 userFormView.DataContext 而不是 user。我使用了 UserControl 替代了 UserForm,并且在你的示例中的 Users 是我想要引入的视图类。我不需要声明 userObject 的实例,因为在我的情况下,那就是我正在设置 .ContentTabItem,也不需要传递 Users user,因为我只是在同一个函数中一起声明了所有内容。谢谢! - vapcguy
UserControl uc = new UserControl(); MyView viewObj = new MyView(); uc.DataContext = viewObj; this.MyTabItem.Content = uc.DataContext;,如果有人感兴趣的话,这是我的情况。 - vapcguy

1
这是一种直接从xaml分配DataContext的方法之一。
示例:App.xaml
<Application.Resources>
     <local:Users x:Key="Users"/>    
</Application.Resources>

示例 UserForm.xaml

<Window DataContext="{StaticResource Users}">
    <Grid>
        <TextBlock Text="Id:"/>
        <TextBox Name="Id" Text="{Binding Path=Id}"/>

        <TextBlock Text="Login:"/>
        <TextBox Name="Login" Text="{Binding Path=Login}"/>

        <TextBlock Text="Name:"/>
        <TextBox Name="Name" Text="{Binding Path=Name}"/>
    </Grid>
</Window>

1
您没有指定 <local:Users x:Key="Users"/> 的定义位置。这个答案不完整。 - Yanick Rochon

0
也许你可以定义一个DependencyProperty来包装对userObject的访问,然后将其绑定到DataContext。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接