我有一个绑定到ObservableCollection的ListView。我面临的问题是,当我分配新集合时,即使我正在调用RaisePropertyChanged
,视图也不会更新。
//TrackIO.GetTracks()
public static ObservableCollection<Track> GetTracks()
{
return tracks;
}
<ListView x:Name="TrackListView"
SelectionMode="Single"
ItemsSource="{Binding Path=ObservableTracks}"
SelectedIndex="{Binding SelectedTrackIndex, Mode=TwoWay}"
>
<!-- Column Binding matches track object properties -->
<ListView.View>
<GridView>
<GridViewColumn Header="Title" Width="600" DisplayMemberBinding="{Binding Title}" />
<GridViewColumn Header="Album" Width="350" DisplayMemberBinding="{Binding Album}" />
<GridViewColumn Header="Artist" Width="250" DisplayMemberBinding="{Binding Artist}" />
<GridViewColumn Header="Duration" Width="200" DisplayMemberBinding="{Binding FormattedDuration}" />
</GridView>
</ListView.View>
</ListView>
private ObservableCollection<Track> _observableTracks;
public ObservableCollection<Track> ObservableTracks
{
get { return _observableTracks; }
private set
{
_observableTracks = value;
RaisePropertyChanged();
}
}
我正在使用MVVM灯来通知viewmodel,将属性设置为不同的集合。
正如您所看到的,我在集合中有项目,因此当我将新集合分配给ObservableTracks属性时。应该调用RaisePropertyChanged()
,但视图为空/什么都不显示。
非常感谢任何帮助。感谢。
答案 0 :(得分:1)
以下代码在我的机器上运行正常。
视图模型:
public class Track
{
public string Title { get; set; }
}
public class MainViewModel : ViewModelBase
{
private ObservableCollection<Track> _observableTracks;
public MainViewModel()
{
DoSomething = new RelayCommand(() => ObservableTracks = new ObservableCollection<Track>() { new Track { Title = "test" } });
}
public ObservableCollection<Track> ObservableTracks
{
get { return _observableTracks; }
private set
{
_observableTracks = value;
RaisePropertyChanged();
}
}
public RelayCommand DoSomething { get; private set; }
}
查看:
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<StackPanel>
<Button Command="{Binding DoSomething}" Content="Do something" />
<ListView x:Name="TrackListView"
SelectionMode="Single"
ItemsSource="{Binding Path=ObservableTracks}"
SelectedIndex="{Binding SelectedTrackIndex, Mode=TwoWay}"
>
<!-- Column Binding matches track object properties -->
<ListView.View>
<GridView>
<GridViewColumn Header="Title" Width="600" DisplayMemberBinding="{Binding Title}" />
<GridViewColumn Header="Album" Width="350" DisplayMemberBinding="{Binding Album}" />
<GridViewColumn Header="Artist" Width="250" DisplayMemberBinding="{Binding Artist}" />
<GridViewColumn Header="Duration" Width="200" DisplayMemberBinding="{Binding FormattedDuration}" />
</GridView>
</ListView.View>
</ListView>
</StackPanel>
您是否忘记设置视图的DataContext?
如果没有,你能分享一个失败的简短例子吗?
答案 1 :(得分:0)
需要调用setter才能调用RaisePropertyChanged
方法。如果它是私有的,则无法从外部代码调用它。如果Resharper将其标记为不更改状态,则应使用注释忽略它(尽管由于方法调用它不应该标记它)。
private ObservableCollection<Track> _observableTracks;
public ObservableCollection<Track> ObservableTracks
{
get { return _observableTracks; }
set
{
_observableTracks = value;
RaisePropertyChanged();
}
}
此外,在设置之前检查相等值是一个很好的模式:
...
set
{
if (_observableTracks == value)
{
return;
}
}
最后,RaisePropertyChanged
会刷新所有属性,您可能只需要更改单个属性通知:
RaisePropertyChanged(() => ObservableTracks);