2014-06-24 94 views
0

我有一个WPF列表视图,它显示一个材质,它的厚度和一个组合框中的厚度单位...... xaml看起来像这样(我取消了所有的可视化设置清晰度):WPF ListView不在PropertyChanged上更新

<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> 

MaterialLayersObservableCollection<MaterialLayer>

MaterialLayer具有用于MaterialName,MaterialThickness和ThicknessUnit(其为厘米和1英寸)为0的性质。 MaterialThickness将内部存储的值(以cm为单位)转换为由ThicknessUnit指定的单位。

当ThicknessUnit更改时,我的DataViewModel将“MaterialLayers”作为属性名称调用PropertyChanged事件处理程序。

因此,当ThicknessUnit发生变化时,我期望MaterialThickness自动更新。 (当调用ThicknessUnit设置方法时,它调用父数据类(MyData)上的一个事件,该事件调用DataViewModel上的事件调用的PropertyChanged处理程序。)从DataViewModel

相关代码从迈德特

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); 
    } 
} 

相关代码

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)); 
     } 
    } 

相关代码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); 
     } 
    } 

} 

任何人都可以帮忙吗?

+2

WPF不会重新绑定UI如果支撑数据的实例是和以前一样。您似乎在整个ItemsSource集合中引发PropertyChanged,这不会导致任何结果。顺便说一句,提高与实际财产的定义不同的类别的财产更改也不会导致任何结果。发布ViewModel和数据项的相关代码。 –

+0

@HighCore我添加了请求的代码。 PropertyChanged从ViewModel被调用。如何正确调用子项目上的属性changed?我尝试过“MaterialThickness”,但没有奏效。 –

回答

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)); 
    } 
} 
+0

感谢您的回复,解决了问题。我只是没有正确理解PropertyChanged需要从哪里来,但答案是有道理的。上述唯一的变化是,在我的ThicknessUnit设置器中,我还需要调用NotifyPropertyChanged(“MaterialThickness”)来获取该列表视图中要更新的字段。再次感谢。 –