我有一个WPF列表视图,显示一个材料,它的厚度,以及组合框中厚度的单位... xaml看起来像这样(为了清晰起见,我删除了所有可视化设置):< / p>
<ListView ItemsSource="{Binding Path=MaterialLayers}" IsSynchronizedWithCurrentItem="True">
<ListView.Resources>
<x:Array x:Key="DistanceUnitItems" Type="sys:String" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String>cm</sys:String>
<sys:String>inches</sys:String>
</x:Array>
<DataTemplate x:Key="ThicknessUnit">
<ComboBox ItemsSource="{StaticResource DistanceUnitItems}" SelectedIndex="{Binding ThicknessUnit}" />
</DataTemplate>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Material Name" DisplayMemberBinding="{Binding MaterialName}"/>
<GridViewColumn Header="Material Thickness" DisplayMemberBinding="{Binding MaterialThickness}"/> />
<GridViewColumn Header="Thickness Unit" CellTemplate="{StaticResource ThicknessUnit}" />
</GridView>
</ListView.View>
</ListView>
MaterialLayers
是ObservableCollection<MaterialLayer>
MaterialLayer具有MaterialName,MaterialThickness和ThicknessUnit的属性(cm表示0,英寸表示1)。 MaterialThickness将内部存储的值(以cm为单位)转换为ThicknessUnit指定的单位。
当ThicknessUnit改变时,我的DataViewModel用&#34; MaterialLayers&#34;调用PropertyChanged
事件处理程序。作为财产名称。
所以,我希望在更改ThicknessUnit时自动更新MaterialThickness。
我调试了它,并且调用了PropertyChanged(&#34; MaterialLayers&#34;)。(当调用ThicknessUnit set方法时,它调用父数据类(MyData)上的事件,在DataViewModel上调用一个调用PropertyChanged处理程序的事件。)
DataViewModel的相关代码
public delegate void DataChangedHandler(String identifier);
public DataViewModel()
{
Data = new MyData();
Data.DataChanged += new DataChangedHandler(RaisePropertyChanged);
}
public ObservableCollection<XTRRAMaterialLayer> MaterialLayers
{
get { return _data.MaterialLayers; }
set { }
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
// take a copy to prevent thread issues
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
MyData的相关代码
public class XTRRAData
{
public ObservableCollection<XTRRAMaterialLayer> MaterialLayers { get; set; }
public event DataChangedHandler DataChanged;
public MyData()
{
MaterialLayers = new ObservableCollection<MaterialLayer>();
}
public void myDataChanged(String identifier)
{
DataChanged(identifier);
}
public void AddLayer()
{
MaterialLayer layer = new MaterialLayer() { MaterialName="Test", MaterialThickness=5, ThicknessUnit=0 };
layer.DataChanged += new DataChangedHandler(myDataChanged);
}
}
MaterialLayer的相关代码
public class XTRRAMaterialLayer
{
public XTRRAMaterialLayer()
{
_thicknessUnit = 0; // cm
}
public event DataChangedHandler DataChanged;
public String MaterialName { get; set; }
public double MaterialThickness
{
get
{
switch (_thicknessUnit)
{
default:
case 0:
return DIST;
case 1:
return DIST * 0.393700787;
}
}
set
{
switch (_thicknessUnit)
{
default:
case 0:
DIST = value;
break;
case 1:
DIST = value / 0.393700787;
break;
}
}
}
public int _thicknessUnit;
public int ThicknessUnit
{
get { return(int) _thicknessUnit; }
set
{
_thicknessUnit = (eThicknessUnits)value;
FireDataChanged("MaterialLayers");
}
}
public void FireDataChanged(String identifier)
{
if(DataChanged!=null)
{
DataChanged(identifier);
}
}
}
有人可以帮忙吗?
答案 0 :(得分:2)
您需要在要更改的属性的类中实现INotifyPropertyChanged - 在您的情况下是XTRRAMaterialLayer,并在属性更改时引发PropertyChanged事件。
您的属性应如下所示:
public int ThicknessUnit
{
get { return(int) _thicknessUnit; }
set
{
_thicknessUnit = (eThicknessUnits)value;
NotifyPropertyChanged();
}
}
NotifyPropertyChanged事件处理程序:
public event PropertyChangedEventHandler PropertyChanged;
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}