我在WPF中有一个ListView元素,如下所示:
<ListView Grid.Row="6" Margin="10" Name="ObservationsListView" SelectionChanged="ObservationsListView_SelectionChanged_1">
<ListView.View>
<GridView>
<GridViewColumn Header="Observation" Width="122" DisplayMemberBinding="{Binding observationStr}" />
<GridViewColumn Header="Value" Width="122" DisplayMemberBinding="{Binding valueStr}" />
<GridViewColumn Header="Hidden State" Width="122" DisplayMemberBinding="{Binding stateStr}" />
</GridView>
</ListView.View>
</ListView>
我将以下结构绑定到它:
public struct ObservationStatePair
{
public AddressObservationGenerator.Observation observation { get; set; }
public AddressObservationGenerator.Observation state { get; set; }
public string observationStr { get; set; }
public string stateStr { get; set; }
public string valueStr { get; set; }
};
我将一个ObservationStatePair数组设置为ListView的itemsSource,它正确地改变了它的内容。但另外,我想修改&#34; stateStr&#34;根据需要,ListView的itemsSource当前选择的ObservationStatePair项的字段。为此,我做了以下修改:
app.currentSequence[ObservationsListView.SelectedIndex].stateStr = selectedState;
ObservationsListView.ItemsSource = app.currentSequence;
ObservationsListView是我的ListView,currentSequence是我想要修改的ObservationStatePair对象的数组。但是这个数据源的更新没有反映在UI中,ListView的内容不会改变。
我在这里遗漏了什么吗?我还应该做些什么才能更新ListView的数据源?
答案 0 :(得分:2)
有两个原因导致它无效:
您没有实施INotifyPropertyChanged
接口,因此绑定系统无法检测属性值何时发生变化
ObservationStatePair
是一个结构,这意味着按值复制。所以视图没有引用原始对象;相反,它引用了对象的盒装副本,因此当您修改原始对象时,更改不会反映在视图引用的更改上。你应该使用一个类。
一般来说,你应该总是避免可变结构,因为它们是bug的常见来源。有关详细信息,请参阅此问题:Why are mutable structs evil?
至于为什么这段代码不起作用:
app.currentSequence[ObservationsListView.SelectedIndex].stateStr = selectedState;
ObservationsListView.ItemsSource = app.currentSequence;
再次设置ItemsSource
无效,因为它与之前的数组相同(我假设currentSequence
是一个数组,否则第一行不会编译)。作为一种变通方法,可以将ItemsSource
设置为null,然后再将数组分配给它。但那不是我推荐的;您应该ObservationStatePair
并实施INotifyPropertyChanged
。