为什么双向绑定不能按预期方式工作?

时间:2020-09-29 13:48:49

标签: wpf data-binding two-way-binding

我需要绑定方面的帮助。双向模式根本不起作用。 我用传递给构造函数的数据填充窗口,并且工作正常。 问题是,即使我使用双向绑定,也无法重写在窗口控件中估算的某些数据。 下面是我打开窗口的方式

    var tempInregistrare = BaseConnection.GetInregistrareById(itemSelected.InregistrareId.ToString());
                var tichet = new TichetView(new InregistrareModel { 
                    Id =tempInregistrare.Id,
                    NumeFurnizor = tempInregistrare.NumeFurnizor,
                    IdFurnizor = tempInregistrare.IdFurnizor,
                    NumeProdus = tempInregistrare.NumeProdus......
ticket.Show();

这里是DataContext设置为self的窗口构造函数。

  public TichetView(InregistrareModel inregistrare)
  {
            InitializeComponent();
            InregistrareModel = inregistrare;
            DataContext = this;
            grdButtonsPrint.Visibility = Visibility.Visible;
   }

  public InregistrareModel InregistrareModel
        {
            get => inregistrareModel;
            set
            {
                if (value != inregistrareModel)
                {
                    inregistrareModel = value;
                    NotifyPropertyChanged();
                }
            }
        }
 public class InregistrareModel
    {
        public int Id { get; set; }
        public int IdProdus { get; set; }
        public int IdFurnizor { get; set; }
        public string NumeProdus { get; set; }
        public string NumeFurnizor { get; set; }
        public string NrAuto { get; set; }
        public string NumeSofer { get; set; }
        public double CantitateInitiala { get; set; }
        public double CantitateIesire { get; set; }
        public double Umiditate { get; set; }
        public double CantitateScazuta { get; set; }
        public double CantitateMarfa { get; set; }
        public DateTime DataIntrare { get; set; }
        public DateTime DataIesire { get; set; }
        public FurnizorModel Furnizor { get; set; }
        public int NIR { get; set; }
    }

这是窗口的Xaml

                <TextBlock Grid.Row="2" Grid.Column="2" VerticalAlignment="Center">Intrare</TextBlock>                
                <TextBox Grid.Row="2" Grid.Column="3" Text="{Binding InregistrareModel.CantitateInitiala}"/>
   
                
                <TextBlock Grid.Row="4" Grid.Column="2" VerticalAlignment="Center">Umiditatea (%)</TextBlock>
                <TextBox x:Name="txtUmiditate" Grid.Row="4" Grid.Column="3" IsReadOnly="False" Text="{Binding InregistrareModel.Umiditate, Mode=TwoWay}"/>   
                
                <TextBlock Grid.Row="5" Grid.Column="2" VerticalAlignment="Center">Cantitatea scazuta</TextBlock>
                <TextBox x:Name="txtCantitateScazuta" Grid.Row="5" Grid.Column="3" IsReadOnly="False" Text="{Binding InregistrareModel.CantitateScazuta, Mode=TwoWay}"/>
                
                <TextBlock Grid.Row="6" Grid.Column="2" VerticalAlignment="Center">Iesire</TextBlock>
                <TextBox Grid.Row="6" Grid.Column="3" Text="{Binding InregistrareModel.CantitateIesire}"/>
                
                <TextBlock Grid.Row="7" Grid.Column="2" VerticalAlignment="Center">Dată iesire</TextBlock>
                <TextBox Grid.Row="7" Grid.Column="3" Text="{Binding InregistrareModel.DataIesire,StringFormat='{}{0:HH:HH dd/M/yyyy}'}"/>
                
                <TextBlock Grid.Row="10" Grid.Column="2" VerticalAlignment="Center">Net</TextBlock>
                <TextBox Grid.Row="10" Grid.Column="3" Text="{Binding InregistrareModel.CantitateMarfa}"/>

所有文本框都填充有数据,需要我手动填写的第二和第三个。 我现在无法实现的目标是从第一个文本框(InregistrareModel.CantitateInitiala)中获取数据以在第3个文本框(txtCantitateScazuta)中键入一些数据,并在最后一个文本框中显示结果,以便在用此数据更新数据库之后。 / p>

2 个答案:

答案 0 :(得分:0)

  1. 您应将ViewModel设置为单独的文件/类。我们称之为TichetViewModel。此类应具有InregistrareModel。像这样:
public class TichetViewModel : ObservableObject
{
    private InregistrareModel _InregistrareModel;
    public InregistrareModel InregistrareModel
    {
        get { return _InregistrareModel; }
        set
        {
            if (value != _InregistrareModel)
            {
                _InregistrareModel = value;
                NotifyPropertyChanged();
            }
        }
    }

    public TichetViewModel()
    {
        InregistrareModel = new InregistrareModel();
    }
}

  1. 然后在您的代码后面或xaml中设置DataContext中的TichetView

后面的代码:

TichetView.xaml.cs

public TichetView()
{
    InitializeComponent();
    DataContext = new TichetViewModel();
}

或xaml

TichetView.xaml

<Window.DataContext>
    <local:TichetViewModel />
</Window.DataContext>

我喜欢在xaml中执行此操作,因为Visual Studio中的Intellisense会选择并基于类自动完成。

  1. INotifyPropertyChanged的属性实施InregistrareModel。像这样:
public class InregistrareModel : ObservableObject
{
    private int _Id;
    public int Id
    {
        get { return _Id; }
        set
        {
            if (value != _Id)
            {
                _Id = value;
                NotifyPropertyChanged();
            }
        }
    }

    private string _NumeProdus;
    public string NumeProdus
    {
        get { return _NumeProdus; }
        set
        {
            if (value != _NumeProdus)
            {
                _NumeProdus = value;
                NotifyPropertyChanged();
            }
        }
    }
}

答案 1 :(得分:0)

我完全同意@Peter Boone的观点。 您在解决方案中有很多严重的体系结构错误,因此有充分的理由需要完全重做。 但是,如果您没有这样的机会,请尝试实施此选项。

对于更改的字段(TextBox,TextBlock),在Window中声明属性。 在这些属性的主体中,实现与父容器(InregistrareModel)和其他属性的通信。

假设您有一个CantitateInitiala属性,该属性会影响CantitateScazuta属性的值。

    public InregistrareModel InregistrareModel
    {
        get => inregistrareModel;
        set
        {
            if (value != inregistrareModel)
            {
                inregistrareModel = value;
                NotifyPropertyChanged();
                CantitateInitiala = InregistrareModel.CantitateInitiala;
            }
        }

    public double CantitateInitiala
    {
        get => InregistrareModel.CantitateInitiala;
        set
        {
            if (value != InregistrareModel.CantitateInitiala)
            {
                InregistrareModel.CantitateInitiala = value;
                NotifyPropertyChanged();

                // Calculation of the CantitateScazuta value
                double cantSc = CantitateInitiala / 123.45;

                CantitateScazuta = cantSc;
            }
        }
    }
    public double CantitateScazuta
    {
        get => InregistrareModel.CantitateScazuta;
        set
        {
            if (value != InregistrareModel.CantitateScazuta)
            {
                InregistrareModel.CantitateScazuta = value;
                NotifyPropertyChanged();
            }
        }
    }

在XAML中,更改以下字段的绑定:

            <TextBlock Grid.Row="2" Grid.Column="2" VerticalAlignment="Center">Intrare</TextBlock>                
            <TextBox Grid.Row="2" Grid.Column="3" Text="{Binding CantitateInitiala}"/>

            
            <TextBlock Grid.Row="4" Grid.Column="2" VerticalAlignment="Center">Umiditatea (%)</TextBlock>
            <TextBox x:Name="txtUmiditate" Grid.Row="4" Grid.Column="3" IsReadOnly="False" Text="{Binding InregistrareModel.Umiditate, Mode=TwoWay}"/>   
            
            <TextBlock Grid.Row="5" Grid.Column="2" VerticalAlignment="Center">Cantitatea scazuta</TextBlock>
            <TextBox x:Name="txtCantitateScazuta" Grid.Row="5" Grid.Column="3" IsReadOnly="False" Text="{Binding CantitateScazuta, Mode=TwoWay}"/>

Нонужнотщательнопродуматьалгоритмзависимостейсвойстввтомслучае, ТоеньтолькоизменениеCantitateInitialaвлияетназначениеCantitateScazuta,нотакжесуществуетобратнаязависима

相关问题