我有一个非常简单的ListView
样式GridView
。单元格绑定到ObservableCollection
元素的某些属性。我不知道为什么没有显示。我正在考虑在集合包含的元素类中实现INotifyPropertyChanged
,但是一旦元素被构造并添加到集合中,它就永远不会被改变,所以它应该正常工作。
C#:
public ObservableCollection<SceneElement> SceneObjects { get; set; }
...
SceneObjects.Add(new Camera());
SceneObjects.Add(new Cuboid(20, 30, 40));
Camera
和Cuboid
都继承自SceneObject
(SceneObject
&lt; - Figure
&lt; - Cuboid
和SceneObject
&lt; - Camera
)
XAML:
<ListView Grid.Column="2" Margin="5"
ItemsSource="{Binding }"
DataContext="{Binding SceneObjects}"
ScrollViewer.CanContentScroll="True">
<ListView.Resources>
<GridView x:Key="StyleOne">
<GridViewColumn Header="Type" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="1" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Position" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="X: " />
<TextBlock Text="{Binding Position.X, RelativeSource={RelativeSource Mode=FindAncestor}}" />
<TextBlock Text=" Y: " />
<TextBlock Text="{Binding Position.Y}" />
<TextBlock Text=" Z: " />
<TextBlock Text="{Binding Position.Z}" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.Resources>
<ListView.Style>
<Style TargetType="ListView">
<Setter Property="View" Value="{StaticResource StyleOne}" />
</Style>
</ListView.Style>
</ListView>
Position
属性在抽象SceneElement
类中定义。
Position
&#39; X
,Y
和Z
也是属性。
修改
这解决了这个问题:
private ObservableCollection<SceneElement> sceneObjects;
public ObservableCollection<SceneElement> SceneObjects
{
get
{
return sceneObjects;
}
set
{
sceneObjects = value;
NotifyPropertyChanged("SceneObjects");
}
}
任何人都可以解释为什么这是必要的吗?到目前为止,我已经使用过ObservableCollection
个严重的时间,而且它总是在没有通知的情况下工作。
答案 0 :(得分:1)
您的应用程序未显示有关集合的信息的原因是UI未发现任何更改
如果在使用之前未初始化所述集合,则使用ObservableCollection
并不保证将显示结果。由于它是ViewModel上的普通属性,因此需要通知所述对象(在本例中为ObservableCollection
)是否已更改,而不是在集合内部的意义项中。
这是因为 NOT 引发了PropertyChanged
的{{1}}事件,这对使用SceneObjects
的{{1}}个应用至关重要。
答案 1 :(得分:-2)
在wpf系统尝试创建绑定时,你的observablecollection为null,如上面的xamimax所述。
在构造函数中实例化你的observablecollection,稍后你可以添加它们,它们会出现。
例如,以下工作原理是因为我首先实例化了observable集合,然后在5秒后添加了项目。
public MainWindow()
{
InitializeComponent();
this.SceneObjects = new ObservableCollection<MyClass>();
Task.Delay(5000).ContinueWith((old) =>
{
this.Dispatcher.Invoke(() =>
{
this.sceneObjects.Add(new MyClass("name"));
this.sceneObjects.Add(new MyClass("name"));
});
});
this.DataContext = this;
}
这是一个不起作用的例子,因为我在wpf系统试图绑定它之后5秒实例化observable集合:
public MainWindow()
{
InitializeComponent();
Task.Delay(5000).ContinueWith((old) => { this.SceneObjects = new ObservableCollection<MyClass> { new MyClass("name"), new MyClass("name") }; });
this.DataContext = this;
}
并且正如您已经意识到的那样,您可以抛出propchanged以使wpf系统显示这些项目,但我认为您应该先简单地实例化observablecollection,这样您就不需要在以后抛出propchanged。