将Viewmodel绑定到View [英] Binding Viewmodel to View

查看:80
本文介绍了将Viewmodel绑定到View的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

MainWindow.xaml

<Window x:Class="SDT.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        mc:Ignorable="d"
        xmlns:viewModels="clr-namespace:SDT.ViewModels"
        Height="500" Width="700" WindowStyle="None" AllowsTransparency="False" ResizeMode="NoResize" Background="#FF2C2C2C"
        TextElement.Foreground="{DynamicResource MaterialDesignBody}" TextElement.FontWeight="SemiBold">

    <Window.DataContext>
        <viewModels:UserViewModel />
    </Window.DataContext>

    <Grid>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="308,90,0,0" TextWrapping="Wrap" Text = "{Binding Login}" VerticalAlignment="Top" Width="120"/>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="152,200,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=FirstName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
        <Button Content="Submit" Command="{Binding SubmitLoginDataCommand}" HorizontalAlignment="Left" Margin="567,259,0,0" VerticalAlignment="Top" Width="75"/>
    </Grid>
</Window>

MainWindows.cs

public partial class MainWindow : Window
{
    UserViewModel userViewModel = new UserViewModel();
    public MainWindow()
    {
        InitializeComponent();
        DataContext = userViewModel;

    }
}

UserViewmodel

public class UserViewModel : INotifyPropertyChanged
{
    private UserService userService = new UserService();

    public string _firstName;

    public string Login { get; set; }

    public void SubmitLoginData(object loginData)
    {
        userService.CheckUserExist(Login);
    }

    public ICommand SubmitLoginDataCommand => new RelayCommand(SubmitLoginData, param => true);

    public string FirstName
    {
        get { return _firstName; }
        set
        {
            if (_firstName != value)
            {
                _firstName = value;
                OnPropertyChanged("FirstName");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

您好。
名字绑定有什么问题?
文本框什么也不显示。
公用字符串FirstName {} -FirstName在调试中很有价值。
我尝试不使用 Window.DataContext ,并且仅尝试使用 Text = {Binding FirstName} ,但没有成功。
登录绑定可以正常工作。

Hello. What is wrong with FirstName binding? Textbox shows nothing. public string FirstName{} - FirstName here have value in debugging. I tried without Window.DataContext and only with Text="{Binding FirstName}" but without success. Login binding working fine.

推荐答案

让我们测试一下您的绑定!让我们在表单中添加一个文本块,然后将FirstName属性绑定到它。如果绑定正常工作,则在文本框中中输入的任何内容都应显示在文本中。

Let's test your binding! Let's add a text block to your form, and bind the FirstName property to it. Whatever you enter in the Textbox should be displayed in the textblock if your binding is working correctly.

您的MainWindow.xaml应该看起来像这样:

Your MainWindow.xaml should look something like this:

<Window x:Class="SDT.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:viewModels="clr-namespace:Junk.cats"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">

<Grid>
    <TextBox HorizontalAlignment="Left" Height="23" Margin="308,90,0,0" TextWrapping="Wrap" Text = "{Binding Login}" VerticalAlignment="Top" Width="120"/>
    <TextBox HorizontalAlignment="Left" Height="23" Margin="152,200,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=FirstName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
    <Button Content="Submit" Command="{Binding SubmitLoginDataCommand}" HorizontalAlignment="Left" Margin="567,259,0,0" VerticalAlignment="Top" Width="75"/>
    <TextBlock HorizontalAlignment="Left" Height="32" Margin="140,247,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="346"> 
       <Run Text="First Name: "/>
       <Run Text="{Binding Path=FirstName}"/>
    </TextBlock>
</Grid>

我希望此测试会工作,然后您会发现get / set属性和UI更新没有问题。我相信您的问题现在出在UserViewModel的实例(副本)上。

I expect that this test will work, and you're going to see that you're not having an issue with your get/set properties and UI updates. I believe your issue is now with the 'instance' (copy) of the UserViewModel.

假装我们正在处理打印文档。当使用= new UserService();时作业,您正在打印我们的文档的新副本。如果我们打印一个新文档并将其提供给MainWindow.cs(我们将其称为 Bob),则 AND ,然后在userService代码中打印一个新副本(我们将其称为 Frank)-这些是文档的两个独立实例/副本。

Let's pretend we're working with a printed document. When you use the = new UserService(); assignment, you're printing a fresh copy of our document. If we print a new document and give it to MainWindow.cs (Let's call it "Bob"), AND you then print a new copy in your userService code (Let's call this "Frank") - these are two independent instances / copies of the document.

我们需要一次创建该对象,并告诉 Bob和 Frank使用该对象的相同副本。不用担心,这比您想象的要容易,并且您会在使用它时开始习惯它。

We need to make this object once, and tell "Bob" and "Frank" to work with the same copy of the object. Don't worry, this is easier than you think, and you'll start getting used to it as you use it.

我将使用一些 STATIC 字段来简化故障排除-您无需创建静态实例即可完成此工作,但是您需要确保共享类的实例可供任何需要的人使用。

I'm going to use some STATIC fields to simplify your troubleshooting - you do not need to create a static instance to make this work, but you do need to make sure your instance of the shared class is available to whoever needs it.

第1步-创建一个新类,我们将其称为视图。
步骤2-将类设为静态
步骤3-在此处创建公共静态userViewModel

Step 1 - Create a new class, let's call it 'Views'. Step 2 - Make the class public static Step 3 - Create a Public static userViewModel here:

public static class views
{
    public static UserViewModel userViewModel = new UserViewModel();
}

现在-让我们更改MainWindow.cs以使用此类的共享实例:

Now - Let's change your MainWindow.cs to use the shared instance of this class:

    public partial class MainWindow : Window
{


    public MainWindow()
    {
        InitializeComponent();
        DataContext = views.userViewModel;

    }
}

您需要做的最后一件事-使您的外部函数与'userViewModel'的相同副本一起使用!我没有您提供的代码,因此我假装您的函数名为 YourFunctioNToChangeTheName,它位于您的 UserService类中:

The last thing you need to do - Make your external function work with the same copy of the 'userViewModel'! I don't have that code from you, so I'm pretending your function is called 'YourFunctioNToChangeTheName', and it's located in your 'UserService' class:

    public class UserService
{
   public void YourFunctionToChangeTheName()
    {
        views.userViewModel.FirstName = "FRANK"; 
    }
}

在这里发现的关键是不创建新的 UserViewModel-您正在重新使用MainWindow.cs绑定的相同实例-因此,UI现在会收到属性更改通知!

The key thing to spot here is that you're not creating a new "UserViewModel" - you're re-using the same instance that the MainWindow.cs is bound to - so the UI is getting a 'property changed notification' now!

请记住,UserViewModel(类)本身不是静态的,我们已经创建了一个共享/静态实例,可以从您程序的任何位置对其进行访问。我建议使用这种方法,以便您可以了解实例的基础知识:)

Remember, the UserViewModel (class) itself isn't static, we've created a shared / static instance of it that can be accessed from anywhere in your program. I suggested this approach so that you can learn the basics of an instance :)

祝您好运!

这篇关于将Viewmodel绑定到View的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆