【问题标题】:How do I get databinding to work with null class?如何让数据绑定与空类一起使用?
【发布时间】:2017-10-05 06:24:48
【问题描述】:

我正在开发一个 WPF 应用程序,它几乎是一个应用程序表单。它有多个文本字段。这是我使用 MVVM 模型做的第一个应用程序,所以我确信我遗漏了一些东西。我有很多文本框,所以我展示的代码将集中在四个文本字段上,第四个字段假设在其他三个更改时总计。但是我拥有的数据绑定没有执行。我无法弄清楚为什么当我在文本框 txbFamO 中输入数字时,FamilyO get 语句没有被执行。我没有正确绑定吗?我没有正确初始化类申请人吗?

这是我的 XAML:

<UserControl x:Class="ApplicationForm.Views.ApplicationView" 
    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:local="clr-namespace:ApplicationForm"
    xmlns:model="clr-namespace:ApplicationForm.Model"
    xmlns:views="clr-namespace:ApplicationForm.Views"
    xmlns:viewModel="clr-namespace:ApplicationForm.ViewModel"
    mc:Ignorable="d"
    Height="1100" Width="800" Background="#FFDAFDF2">

<Grid x:Name="grdAppForm">
    <Grid x:Name="grdAppFormGrid" DataContext="{Binding Applicant}"
          Height="881" Width="700" Margin="0,0,0,0">
        <Label x:Name="lblFamilySize" Content="Family Size:" Height="28" Width="102" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="372,71,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16" />
        <Label x:Name="lblFamO" Content="O:" Height="28" Width="27" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="471,71,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
        <TextBox x:Name="txbFamO" Text="{Binding FamilyO, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="22" Width="20" HorizontalAlignment="Left" 
                 VerticalAlignment="Top" Margin="496,71,0,0" FontFamily="Arial" FontSize="16" 
                 FontWeight="Bold" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
        <Label x:Name="lblFamA" Content="A:" Height="28" Width="25" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="516,71,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
        <TextBox x:Name="tbxFamA" Text="{Binding FamilyA, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Height="22" Width="20" HorizontalAlignment="Left" 
                 VerticalAlignment="Top" Margin="541,71,0,0" FontFamily="Arial" FontSize="16" 
                 FontWeight="Bold" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
        <Label x:Name="lblFamC" Content="C:" Height="28" Width="25" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="562,71,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
        <TextBox x:Name="txtFamC" Text="{Binding FamilyC, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
                 Height="22" Width="20" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="587,71,0,0" FontFamily="Arial" FontSize="16" FontWeight="Bold" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
        <Label x:Name="lblEqual" Content="=" Height="28" Width="20" HorizontalAlignment="Left" VerticalAlignment="Top" 
               Margin="611,71,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
        <TextBox x:Name="tbxFamTot" Text="{Binding FamilyTotal, 
                Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" Height="22" Width="30" 
                HorizontalAlignment="Left" VerticalAlignment="Top" Margin="634,71,0,0" FontFamily="Arial" 
                FontWeight="Bold" FontSize="16" BorderBrush="Black" BorderThickness="0,0,0,3" IsTabStop="False" 
                 VerticalContentAlignment="Bottom"/>
    </Grid>
</Grid>

我的模型代码:

namespace ApplicationForm.Model
{
public class ApplicationModel
{
}


public class Applicant : INotifyPropertyChanged
{
    private string familyO;
    private string familyA;
    private string familyC;

    public string FamilyO
    {
        get { return familyO; }

        set
        {
            if (familyO != value)
            {
                familyO = value;
                RaisePropertyChanged("FamilyO");
                RaisePropertyChanged("FamilyTotal");
            }
        }
    }

    public string FamilyA
    {
        get { return familyA; }

        set
        {
            if (familyA != value)
            {
                familyA = value;
                RaisePropertyChanged("FamilyA");
                RaisePropertyChanged("FamilyTotal");
            }
        }
    }

    public string FamilyC
    {
        get { return familyC; }

        set
        {
            if (familyC != value)
            {
                familyC = value;
                RaisePropertyChanged("FamilyC");
                RaisePropertyChanged("FamilyTotal");
            }
        }
    }

    public string FamilyTotal
    {
        get
        {
            return (Convert.ToInt16(familyO) + Convert.ToInt16(familyA) + Convert.ToInt16(familyC)).ToString();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

}

我的 ViewModel 代码:

namespace ApplicationForm.ViewModel
{
class ApplicationViewModel : INotifyPropertyChanged
{
    // If modifying these scopes, delete your previously saved credentials
    // at ~/.credentials/sheets.googleapis.com-dotnet-quickstart.json
    static string[] Scopes = { SheetsService.Scope.Spreadsheets };
    static string ApplicationName = "NB Food Pantry Application";


    public RelayCommand LoadApplicantCommand
    {
        get;
        set;
    }

    public RelayCommand ClearDataCommand
    {
        get;
        set;
    }

    public RelayCommand PrintApplicantCommand
    {
        get;
        set;
    }

    public RelayCommand CloseCommand
    {
        get;
        set;
    }

    public Applicant applicants;





    public ApplicationViewModel()
    {
        applicants = new Applicant();
        PrintApplicantCommand = new RelayCommand(PrintApplicant);
        ClearDataCommand = new RelayCommand(ClearApplicantData);
        CloseCommand = new RelayCommand(CloseApp);
    }

    public ObservableCollection<Applicant> Applicants
    {
        get;
        set;
    }
}

}

【问题讨论】:

  • “我展示的代码将集中在四个文本字段上” -- 您展示的代码应该最少。当然,它不需要 四个 文本框,加上所有其他的东西,只是为了证明你遇到的任何问题。请阅读minimal reproducible example。另请参阅How to Ask,尤其是该页面底部链接的文章。也就是说,您似乎完全没有在ApplicationViewModel 类中实现INotifyPropertyChanged。而且我在任何地方都看不到一个Applicant 属性。您是否查看了调试输出以了解存在哪些绑定错误?
  • 那么"a null class"到底是什么意思?
  • 我如何未能实现 INotifyPropertyChanged?我的 ApplicationViewModel 在其定义中有 INotifyPropertyChanged,在我的设置器中有 RaisePropertyChanged。在我的 XAML 中,我将 datacontext 设置为我的申请人类,并在类字段上为相应的文本框设置绑定。当我单步执行调试器时,不会调用设置器代码。我在不知道在哪里断开连接。我假设我在启动时没有正确创建申请人的实例。我不确定如何创建绑定可以使用的申请人类,启动时的所有值都将为空或 null
  • “我的 ApplicationViewModel 在其定义中有 INotifyPropertyChanged,在我的 setter 中有 RaisePropertyChanged” -- 前者是真的,后者不是。您显示的所有属性都是隐式实现,例如public RelayCommand LoadApplicantCommand { get; set; }“在我的 XAML 中,我将 datacontext 设置为我的申请者类”——不,你没有。您将 DataContext 属性设置为不存在的 Applicant 属性值。同样,您是否查看了调试输出以了解存在哪些绑定错误?如果您需要帮助,您需要改进问题中的代码示例。
  • 该属性Applicant 出现在`DataContext="{Binding Apply}"` 中的位置?它在哪里居住?

标签: c# wpf mvvm data-binding


【解决方案1】:

我已经解决了我的问题。我没有创建申请人的实例并初始化元素。

【讨论】:

    猜你喜欢
    • 2016-04-15
    • 2020-01-11
    • 1970-01-01
    • 2019-08-22
    • 2017-05-10
    • 2018-05-23
    • 1970-01-01
    • 2017-06-23
    • 2021-05-30
    相关资源
    最近更新 更多