C# 多重绑定未更新源属性的文本框
我有一个列表框,其中包含02x06形式的字符串列表。。始终为两位数,小写x,两位数,不带空格。它绑定到两个文本框,一个保存本例中的行02,另一个保存列06 这个很好用 现在,我需要将行文本框绑定到代码中的行属性,将列文本框绑定到代码中的列属性。我正试图通过多重绑定实现这一点: XAML: DiePrintConverter类别:C# 多重绑定未更新源属性的文本框,c#,.net,wpf,binding,multibinding,C#,.net,Wpf,Binding,Multibinding,我有一个列表框,其中包含02x06形式的字符串列表。。始终为两位数,小写x,两位数,不带空格。它绑定到两个文本框,一个保存本例中的行02,另一个保存列06 这个很好用 现在,我需要将行文本框绑定到代码中的行属性,将列文本框绑定到代码中的列属性。我正试图通过多重绑定实现这一点: XAML: DiePrintConverter类别: public class DiePrintConverter : IMultiValueConverter { bool row = true; pub
public class DiePrintConverter : IMultiValueConverter
{
bool row = true;
public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
{
if (value[0] == null)
{
return "00";
}
var values = value[0].ToString().Split(new string[] { "x" }, StringSplitOptions.None);
int x = 0;
for (int i = 0; i < values.Count(); i++)
{
if (values[i].ToString().Count() == 1)
{
values[i] = "0" + values[i];
}
}
if (row)
{
row = false;
return values[0].ToString();
}
else
{
row = true;
return values[1].ToString();
}
return "00";
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
wtw是包含所有这些组件的窗口的视图模型。DiePrintNav是一个包含行和列只写属性的类,当txtRow和txtCol值更改时需要更新这些属性。wtw视图模型对象包含DiePrintNav属性,是文本框的数据上下文。“未检查的打印”列表框的数据上下文也是wtw对象,并绑定到wtw的“未检查的打印列表”属性
列表框已正确填写。然后,我可以单击列表框中的任何内容,它也可以镜像到txtRow和txtCol框中,因此IMultiValueConverter类也可以正常工作
问题是,每当txtRow和txtCol框中发生任何更改时,它们各自的属性都不会更新
发生了什么事
任何帮助都将不胜感激
谢谢
Kyle也许您的类DiePrintNav必须实现INotifyPropertyChanged接口。是吗?这可能就是原因。请检查一下
编辑
我现在明白了,您希望从视图更新模型属性。问题似乎是您需要定义多值转换器的ConvertBack方法,这样视图就可以在更改时更新所有属性。这里的另一件事是绑定应该是Mode=TwoWay,因为即使您不想在第一次加载模型时从模型更新视图,您也可能希望视图显示旧的模型值,在这种情况下,需要双向绑定。希望此更新有助于
编辑
请查看这篇文章,这里解释了IMultivalueConverter接口的工作方式,希望有帮助:它不实现INotifyPropertyChanged,因为它不需要。我试图将txtRow和txtCol值绑定到DiePrintNav类中的Row和Col属性。INotifyPropertyChanged只允许DiePrintNav中的更改镜像到文本框中。实际上,我想将文本框中的内容镜像到DiePrintNav中的属性。这些行和列属性是只写的,因为不需要在类之外的任何地方检索这些数据。我刚刚用DiePrintNav代码更新了原始帖子。我不明白为什么我需要实现ConvertBack方法。我在那个里放了一个断点,不管我做什么,我都不能让这个方法开火。如果行和列文本框绑定到列表框的selected value属性,并且DiePrintNav类的行和列属性绑定到行和列文本框,我看不出如何需要ConvertBack。@RaulOtaño如果调用此方法,他将得到一个NotImplementedException…对于此方法,调用的每个绑定必须是mode=twoway,您还可以设置update source trigger=changed属性。convert back方法是将您在“仅一个”文本框中的值转换为要在源中设置的倍数值的方法。请检查应答更新中的msdn引用。另外,可能会引发NotImplementedException,而您可能看不到它,因为XAML对用户隐藏异常,一种查看它的方法是查看输出控制台,在调试模式下运行应用程序
lbxUninspectedPrints.DataContext = wtw;
txtRow.DataContext = wtw.DiePrintNav;
txtCol.DataContext = wtw.DiePrintNav;
public class DiePrintConverter : IMultiValueConverter
{
bool row = true;
public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
{
if (value[0] == null)
{
return "00";
}
var values = value[0].ToString().Split(new string[] { "x" }, StringSplitOptions.None);
int x = 0;
for (int i = 0; i < values.Count(); i++)
{
if (values[i].ToString().Count() == 1)
{
values[i] = "0" + values[i];
}
}
if (row)
{
row = false;
return values[0].ToString();
}
else
{
row = true;
return values[1].ToString();
}
return "00";
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class DiePrintNavigation
{
#region Fields
private string row;
private string col;
private DiePrint diePrint;
private DelegateCommand moveUpCommand;
private DelegateCommand moveDownCommand;
private DelegateCommand moveLeftCommand;
private DelegateCommand moveRightCommand;
private DelegateCommand loadMapCommand;
private WaferTrackerWindowViewModel wtw;
#endregion
#region Constructor
public DiePrintNavigation() { }
public DiePrintNavigation(WaferTrackerWindowViewModel wtw)
{
this.wtw = wtw;
}
#endregion
#region Properties
public string Row
{
set
{
row = value;
}
}
public string Col
{
set
{
col = value;
}
}
public DiePrint DiePrint
{
get
{
return diePrint;
}
set
{
diePrint = value;
}
}
public ICommand MoveUpCommand
{
get
{
if (moveUpCommand == null)
{
moveUpCommand = new DelegateCommand(MoveUp);
}
return moveUpCommand;
}
}
public ICommand MoveDownCommand
{
get
{
if (moveDownCommand == null)
{
moveDownCommand = new DelegateCommand(MoveDown);
}
return moveDownCommand;
}
}
public ICommand MoveLeftCommand
{
get
{
if (moveLeftCommand == null)
{
moveLeftCommand = new DelegateCommand(MoveLeft);
}
return moveLeftCommand;
}
}
public ICommand MoveRightCommand
{
get
{
if (moveRightCommand == null)
{
moveRightCommand = new DelegateCommand(MoveRight);
}
return moveRightCommand;
}
}
public ICommand LoadMapCommand
{
get
{
if (loadMapCommand == null)
{
loadMapCommand = new DelegateCommand(LoadMap);
}
return loadMapCommand;
}
}
#endregion
#region Methods
private void Move()
{
DiePrintQueries diePrintQueries = new DiePrintQueries(
DataLibrary.SingulationOne,
DataLibrary.MasksInfo);
diePrint.Name = diePrint.Row.ToString() + "x" + diePrint.Col.ToString();
try
{
diePrint.Mask = diePrintQueries.GetMask(diePrint.Name);
diePrint.LasersPerDie = diePrintQueries.GetLasersPerDie(diePrint.Mask);
diePrint.DieTable = diePrintQueries.GetListOfDie(diePrint.Name);
wtw.WaferMap.DiePrint = diePrint;
wtw.WaferMap.DrawMap();
}
catch (InvalidOperationException)
{
MessageBox.Show(
"Die Print " + diePrint.Name + " does not exist on this wafer.\n" +
"Please move to a die print that exists.",
"Non-Existent Die Print", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
public void MoveUp()
{
// TODO: Catch all these Move Errors!!!
try
{
diePrint.GetRowAndColumn(diePrint.Name);
diePrint.Row = diePrint.Row - 1;
Move();
}
catch (NullReferenceException)
{
}
}
public void MoveDown()
{
diePrint.GetRowAndColumn(diePrint.Name);
diePrint.Row = diePrint.Row + 1;
Move();
}
public void MoveRight()
{
diePrint.GetRowAndColumn(diePrint.Name);
diePrint.Col = diePrint.Col + 1;
Move();
}
public void MoveLeft()
{
diePrint.GetRowAndColumn(diePrint.Name);
diePrint.Col = diePrint.Col - 1;
Move();
}
public void LoadMap()
{
if (diePrint == null)
{
DiePrintQueries diePrintQueries = new DiePrintQueries(
DataLibrary.SingulationOne,
DataLibrary.MasksInfo);
if (this.row.StartsWith("0"))
{
row = row.Remove(0, 1);
}
if (this.col.StartsWith("0"))
{
col = col.Remove(0, 1);
}
diePrint = new DiePrint(this.row + "x" + this.col);
diePrint.Mask = diePrintQueries.GetMask(diePrint.Name);
diePrint.DieTable = diePrintQueries.GetListOfDie(diePrint.Name);
// TODO: dupCode(1)
// Then map the die print
wtw.WaferMap = new DiePrintMapViewModel(diePrint);
wtw.WaferMap.NotifyCanvas += wtw.Update;
wtw.WaferMap.NotifyBluetape += wtw.Update;
wtw.WaferMap.NotifyDieprint += wtw.Update;
wtw.WaferMap.DrawMap();
wtw.FailureCodeManager.DiePrintMap = (DiePrintMapViewModel) wtw.WaferMap;
}
diePrint.Row = Convert.ToInt32(this.row);
diePrint.Col = Convert.ToInt32(this.col);
Move();
}
#endregion
}