ListView 不显示 observablecollection,当新集合分配给绑定 属性 时,即使调用了 RaisePropertyChanged
ListView not showing observablecollection, when a new collection is assigned to bound property, even though RaisePropertyChanged is called
我有一个绑定到 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 light 通知视图模型,将 属性 设置为不同的集合。
如您所见,我在集合中有项目,因此当我将新集合分配给 ObservableTracks 时 属性。 RaisePropertyChanged()
应该被调用,但是视图是 empty/shows 什么都没有。
非常感谢任何帮助。谢谢。
需要调用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);
以下代码在我的机器上运行良好。
视图模型:
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?
如果没有,您能否分享一个失败的简短示例?
我有一个绑定到 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 light 通知视图模型,将 属性 设置为不同的集合。
如您所见,我在集合中有项目,因此当我将新集合分配给 ObservableTracks 时 属性。 RaisePropertyChanged()
应该被调用,但是视图是 empty/shows 什么都没有。
非常感谢任何帮助。谢谢。
需要调用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);
以下代码在我的机器上运行良好。
视图模型:
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?
如果没有,您能否分享一个失败的简短示例?