首页 > 解决方案 > Why twoway binding doen't work as expected?

问题描述

I need some help with binding. Twoway mode doesn't work at all. I fill my window with data passed to the constructor and it's working fine. The problem is that I can't rewrite some data imputed in the window control even if I use Twoway binding. Below is how I open window

    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();

Here is window constructor with DataContext set to 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; }
    }

And here is Xaml of window

                <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}"/>

All text boxes are filled with data expect the second and third that I fill by hand. The goal that I can't achieve right now is to take data from 1st textbox(InregistrareModel.CantitateInitiala) to type in 3rd(txtCantitateScazuta) some data and show the result in the last textbox so after I update my database with this data.

标签: wpfdata-bindingtwo-way-binding

解决方案


  1. You should make the ViewModel a separate file/class. Let's call it TichetViewModel. This class should have the InregistrareModel. Something like this:
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. Then set the DataContext of TichetView in either you code behind or in xaml.

Code behind:

TichetView.xaml.cs

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

or in xaml

TichetView.xaml

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

I like doing this in xaml because the Intellisense in Visual Studio picks this up and autocompletes based on the classes.

  1. Implement INotifyPropertyChanged on the properties of the InregistrareModel. Like this:
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();
            }
        }
    }
}


推荐阅读