WPF ListView没有更新PropertyChanged

本文关键字:更新 PropertyChanged ListView WPF | 更新日期: 2023-09-27 18:10:04

我有一个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>

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

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 ListView没有更新PropertyChanged

你需要实现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));
    }
}