wpf - 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.
解决方案
- You should make the ViewModel a separate file/class. Let's call it
TichetViewModel
. This class should have theInregistrareModel
. 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();
}
}
- Then set the
DataContext
ofTichetView
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.
- Implement
INotifyPropertyChanged
on the properties of theInregistrareModel
. 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();
}
}
}
}
推荐阅读
- ruby - Ugly indention with Sinatra ERB partials
- javascript - 在 Javascript 中完成递归 promise 函数的执行
- swift - Swift OSX Call bash Script
- php - Laravel route not defined while it is
- python - 多线程 XML-RPC (python3.7.1)
- html - Only first
is not showing - sql-server - Will Azure Data Lake Store Gen2 support PolyBase from on-prem SQL Server?
- c++ - C ++当我从另一个类的方法调用一个方法时,它可以工作但不编辑第一个方法的类变量
- java - 微服务和数据库安全
- python - 如何从 for 循环的第二个索引开始