如何在 WPF 中正确绑定我的模型

本文关键字:绑定 我的 模型 WPF | 更新日期: 2023-09-27 18:00:10

我有一个名为ViewModel的类,它实现了INotifyPropertyChanged接口。 在我的 XAML 中,我有 3 个文本框,这些文本框具有与我的 ViewModel 属性匹配的绑定属性:

测试已订购测试已完成测试剩余

我的代码隐藏中有一个 PropertyChanged 事件处理程序。 我有一个上下文"MyContext"附加到XAML窗口。 我不确定为什么当我更改"测试有序"和"测试已完成"值时 UI 不更新。 我希望 UI 在我跳出文本框时更新,但直到我跳出"测试剩余"文本框才会更新。 我的设计缺陷在哪里?

public partial class MainWindow : Window
{
    public ViewModel vm;
    public MainWindow()
    {
        InitializeComponent();
        vm = new ViewModel();
        //ct = new CompletionTime();
        //ct.TestsOrdered = 8000;
        vm.Name = "John Doe";
        vm.TestsCompleted = 0;
        vm.TestsOrdered = 0;
        vm.TestsRemaining = 0;
        this.MyContext.DataContext = vm;
    }
    private void btnName_Click(object sender, RoutedEventArgs e)
    {
        vm.Name = "Joe";
    }
}
public class ViewModel : INotifyPropertyChanged
{
    private string name;
    private int mTestsOrdered;
    private int mTestsRemaining;
    private int mTestsCompleted;
    public string Name
    {
        get { name; }
        set
        {
            if (name != value)
            {
                name = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Name"));
                }
            }
        }
    }

    public int TestsOrdered
    {
        get { return mTestsOrdered; }
        set
        {
            if (mTestsOrdered != value)
            {
                mTestsOrdered = value;
                PropertyChanged(this, new PropertyChangedEventArgs("TestsOrdered"));
            }
        }
    }

    public int TestsCompleted
    {
        get { return mTestsCompleted; }
        set
        {
            if (mTestsCompleted != value)
            {
                mTestsCompleted = value;
                PropertyChanged(this, new PropertyChangedEventArgs("TestsCompleted"));
            }
        }
    }

    public int TestsRemaining
    {
        get { return TestsOrdered - TestsCompleted; }
        set
        {
            if (mTestsRemaining != value)
            {
                mTestsRemaining = value;
                PropertyChanged(this, new PropertyChangedEventArgs("TestsRemaining"));
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

MyContext 是保存 ViewModel 对象的 DataContext。

XAML:

 <Grid Margin="-1,-9,1,9">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="244*"/>
            <ColumnDefinition Width="251*"/>
        </Grid.ColumnDefinitions>
        <TextBox Width="100"  HorizontalAlignment="Center" Margin="96.791,40,54,0" TextWrapping="Wrap" Text="{Binding Path=Name}" VerticalAlignment="Top" Grid.Column="1"/>
        <Button x:Name="btnName" Content="Button" HorizontalAlignment="Left" Margin="171,210,0,0" VerticalAlignment="Top" Width="148" Height="47" Click="btnName_Click" Grid.ColumnSpan="2"/>
        <TextBox Grid.Column="0" HorizontalAlignment="Left" Height="23" Margin="97,84,0,0" TextWrapping="Wrap" Text="{Binding Path=TestsOrdered}" VerticalAlignment="Top" Width="120"/>
        <TextBox Grid.Column="0" HorizontalAlignment="Left" Height="23" Margin="97,112,0,0" TextWrapping="Wrap" Text="{Binding Path=TestsCompleted}" VerticalAlignment="Top" Width="120"/>
        <TextBox Grid.Column="0" HorizontalAlignment="Left" Height="23" Margin="97,140,0,0" TextWrapping="Wrap" Text="{Binding Path=TestsRemaining}" VerticalAlignment="Top" Width="120"/>
    </Grid>

如何在 WPF 中正确绑定我的模型

绑定

和属性已正确编写。但是,问题在于您将视图模型实例分配给Window。您需要在属性DataContext上设置视图模型的实例,绑定才能正常工作。喜欢这个:

 public MainWindow()
{
    InitializeComponent();
    vm = new ViewModel();
    //ct = new CompletionTime();
    //ct.TestsOrdered = 8000;
    vm.Name = "John Doe";
    vm.TestsCompleted = 0;
    vm.TestsOrdered = 0;
    vm.TestsRemaining = 0;
    //this.MyContext.DataContext = vm;
    this.DataContext = vm; // <-- Like so
}

原因是绑定的工作方式。如果没有提供其他源(BindingSourceRelativeSourceElementName属性(,绑定将使用它们所分配到的FrameworkElementDataContext属性。在您的情况下,TextBox.

设置 Window 的 DataContext 属性时,其所有子对象都将继承该对象实例及其子对象,依此类推。

尝试更改视图模型分配,您将看到绑定有效。

//干杯