一、简介
问题描述:
ListView绑定ObservableCollection:增加、删除元素时UI会更新,修改属性时不会更新。相信大家都遇到过类似的问题。
绑定如下:
<!--列表 -->
<Grid Grid.Column="1" Margin="4,8,7,-1">
<ListView Grid.Row="1" Grid.Column="1" Style="{StaticResource ListViewStyle1}" Name="listview_User" ItemContainerStyle="{StaticResource ListViewItemContainerStyle}" ItemsSource="{Binding AccountList,Mode=TwoWay}" SelectedIndex="{Binding SelectIndex}">
<i:Interaction.Triggers>
<!--加载-->
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadedCommand}"/>
</i:EventTrigger>
<!--选中-->
<i:EventTrigger EventName="SelectionChanged">
<!--<prism:InvokeCommandAction Command="{Binding ListViewSelectedCommand}" CommandParameter="{Binding SelectedItems, ElementName=lvPatientList}" />-->
<prism:InvokeCommandAction Command="{Binding ListViewSelectedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource DefaultGridViewColumnHeader}">
<GridViewColumn Header="账户名" Width="290" DisplayMemberBinding="{Binding AccountListName,Mode=TwoWay}"/>
<GridViewColumn Header="账户描述" Width="290" DisplayMemberBinding="{Binding AccountListdescription,Mode=TwoWay}"/>
<!--<GridViewColumn Header="账户类型" Width="290" DisplayMemberBinding="{Binding ElementName=cbb_uerLevel,Path=SelectedItem}"/>-->
<GridViewColumn Header="账户类型" Width="290" DisplayMemberBinding="{Binding AccountListPassWord,Mode=TwoWay}"/>
<GridViewColumn Header="指纹登记" Width="290" DisplayMemberBinding="{Binding AccountListFingerID,Mode=TwoWay}"/>
<GridViewColumn Header="人脸登记" Width="290" DisplayMemberBinding="{Binding AccountListFaceID,Mode=TwoWay}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
集合如下:
private ObservableCollection<AccountList> _accountList = new ObservableCollection<AccountList>();
/// <summary>
///账户列表
/// </summary>
public ObservableCollection<AccountList> AccountList
{
get { return _accountList; }
set { SetProperty(ref _accountList, value); }
}
修改函数如下:
/// <summary>
/// 修改用户信息
/// </summary>
private void ModifyCommandFunc()
{
try
{
if (SelectIndex == -1)
{
EMessageBox.Show("请选择一位需要编辑的账户!", "", EMessageBoxButton.OK, EMessageBoxImage.Warning);
return;
}
if (SelectIndex > -1)//if (SelectIndex >= 0)
{
_accountList[SelectIndex].AccountListName = UserName;
_accountList[SelectIndex].AccountListdescription = Userdescription;
_accountList[SelectIndex].AccountListPassWord = UserPassWord;
_accountList[SelectIndex].AccountListFingerID = AccountFingerID;
_accountList[SelectIndex].AccountListFaceID = AccountFaceID;
//Expression<Func<PatientInfo, bool>> QueryConditionsExpression1 = u => string.IsNullOrEmpty(SearchBoxContent) || u.StudyId.ToString().Contains(SearchBoxContent) || u.PatientId.Contains(SearchBoxContent) || u.PatientName.Equals(SearchBoxContent);
//Expression<Func<PatientInfo, bool>> QueryConditionsExpression2 = u => string.IsNullOrEmpty(null);
//operateDataSheet.SearchFunc(strSearchTable, SelectIndex, QueryConditionsExpression1, QueryConditionsExpression2);
//PreviewList = new ObservableCollection<SeriesInfoListViewModel>(operateDataSheet.GetPreviewListFunc());
}
}
catch (Exception ex)
{
MessageBox.Show("UserInfoConfigViewModel.cs::ModifyCommandFunc()配置页账户列表修改发生失败--" + ex.ToString());
LogHelper.Error("UserInfoConfigViewModel.cs::ModifyCommandFunc()配置页账户列表修改发生失败--" + ex.Message);
}
}
二、本质原因
参考 https://bbs.youkuaiyun.com/topics/390560251
ObservableCollection<Object> 中的Object类继承接口INotifyPropertyChanged 才行,这样就可以直接用集合加下标来自动更新listview了。
二、解决方法
方法1:AccountList直接继承接口INotifyPropertyChanged
参考https://blog.youkuaiyun.com/qq182477985/article/details/80617533
class ViewListItem : INotifyPropertyChanged
{
public string name { get; set; }
private string _status;
public string status {
get
{
return _status;
}
set
{
_status = value;
if( PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("status"));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
方法2:Prism架构中,AccountList直接继承类BindableBase即可
public class AccountList : BindableBase
{
private string _accountListName = null;
/// <summary>
///账户列表
/// </summary>
public string AccountListName
{
get { return _accountListName; }
set { SetProperty(ref _accountListName, value); }
}
}
但是,如果你写成了下面的这种方式,属性就不会自动跟新:
public class AccountList : BindableBase
{
/// <summary>
/// 账户姓名
/// </summary>
public string AccountListName
{
get;
set;
}
}
事件上,类BindableBase本质上也继承了INotifyPropertyChanged