【发布时间】:2014-08-15 07:11:00
【问题描述】:
我有一个 WPF 列表视图,它在组合框中显示材质、厚度和厚度单位...xaml 看起来像这样(为了清晰起见,我删除了所有可视化设置):
<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 的属性(0 表示厘米,1 表示英寸)。 MaterialThickness 将内部存储的值(以厘米为单位)转换为厚度单位指定的单位。
当ThicknessUnit 改变时,我的DataViewModel 调用PropertyChanged 事件处理程序,属性名称为“MaterialLayers”。
所以,我希望 MaterialThickness 在 ThicknessUnit 更改时自动更新。
我已经对其进行了调试,并且调用了 PropertyChanged("MaterialLayers")。(当调用 ThicknessUnit 设置方法时,它调用父数据类 (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);
}
}
}
谁能帮忙?
【问题讨论】:
-
如果支持数据的实例与以前相同,WPF 将不会重新绑定 UI。您似乎正在为整个 ItemsSource 集合提高 PropertyChanged,这不会导致任何结果。顺便说一句,在与实际属性定义不同的类中提升 propertychanged 也不会导致任何结果。贴出 ViewModel 和数据项的相关代码。
-
@HighCore 我添加了请求的代码。从 ViewModel 调用 PropertyChanged。如何在子项上正确调用 propertychanged?我试过“MaterialThickness”,但没有用。
标签: c# wpf listview binding inotifypropertychanged