Dav*_*ope 1 c# wpf binding listview inotifypropertychanged
我有一个 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>
Run Code Online (Sandbox Code Playgroud)
MaterialLayers
是一个ObservableCollection<MaterialLayer>
MaterialLayer 具有 MaterialName、MaterialThickness 和 ThicknessUnit 属性(0 表示厘米,1 表示英寸)。MaterialThickness 将内部存储的值(以厘米为单位)转换为由 ThicknessUnit 指定的单位。
当 ThicknessUnit 更改时,我的 DataViewModel 会调用PropertyChanged
以“MaterialLayers”作为属性名称的事件处理程序。
因此,我希望当 ThicknessUnit 更改时,MaterialThickness 会自动更新。
我已经对其进行了调试,并且 PropertyChanged("MaterialLayers") 被调用。(当调用 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));
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以帮忙吗?
您需要在要更改的属性所在的类中实现INotifyPropertyChanged - 在您的情况下为 XTRRAMaterialLayer,并在属性更改时引发 PropertyChanged 事件。
你的属性应该是这样的:
public int ThicknessUnit
{
get { return(int) _thicknessUnit; }
set
{
_thicknessUnit = (eThicknessUnits)value;
NotifyPropertyChanged();
}
}
Run Code Online (Sandbox Code Playgroud)
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));
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6025 次 |
最近记录: |