我正在尝试将数据绑定到WPF中的自定义数据类型属性FormulaField
。我不明白是否有什么我错过了或者我想做什么不能做?
我遵循了如何绑定一个原语的约定,发现它没有工作,FormulaField
属性没有更新。我还注意到自定义数据类型集方法永远不会被命中。我正在使用MVVM。
模特:
public class OBQModel : NotificationObject
{
private FormulaField _tovLitres;
public FormulaField TOVLitres
{
get
{
if (_tovLitres.UsesFormula)
{
_tovLitres.Value = ConversionHelper.USBarrelsToLitres(_tovBarrels);
}
return _tovLitres;
}
set
{
_tovLitres = value;
RaisePropertyChanged("TOVLitres");
}
}
}
NotificationObject
实施INotifyPropertyChanged
:
public abstract class NotificationObject : DependencyObject, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged<T>(Expression<Func<T>> action)
{
var propertyName = GetPropertyName(action);
RaisePropertyChanged(propertyName);
}
private static string GetPropertyName<T>(Expression<Func<T>> action)
{
var expression = (MemberExpression)action.Body;
var propertyName = expression.Member.Name;
return propertyName;
}
protected internal void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
FormulaField如下所示:
public class FormulaField
{
public bool UsesFormula { get; set; }
public double Value { get; set; }
}
EDIT
在INotifyPropertyChanged
中实现FormulaField
会导致堆栈溢出...
public class FormulaField : INotifyPropertyChanged
{
public bool UsesFormula { get; set; }
public double Value
{
get
{
return Value;
}
set
{
Value = value;
}
}
public event PropertyChangedEventHandler PropertyChanged;
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
模型位于ViewModel中的ObservableCollection
内。
视图的说明:
<StackPanel>
<DataGrid ItemsSource="{Binding OBQModelCollection}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="new TOV (L)" Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox BorderThickness="0"
Text="{Binding TOVLitres.Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
答案 0 :(得分:2)
根据你所写的内容,你在“LiquidGOVLitres”上提出INPC,这似乎没有出现在你的代码清单中,但你绑定到“TOVLitres”。
修复此不一致性会有所帮助,但如果您希望更改其成员作为UI的一部分,则还需要在FormulaField上实现INPC。
ETA:在对代码清单进行澄清编辑之后,剩下的任务是在FormulaField类上实现INPC并相应地引发事件。
另外,如果你使用4.5,你可以调查新的会员信息类,这有助于避免在INPC中使用魔术字符串。
最后,为了语义清晰,将“Value”重命名为“FormulaValue”并不会有什么坏处......
为避免递归,请尝试此模型...
private double _value;
public double Value
{
[DebuggerStepThrough]
get { return _value; }
[DebuggerStepThrough]
set
{
if (Math.Abs(value - _value) > Double.Epsilon)
{
_value = value;
OnPropertyChanged("Value");
}
}
}