列表视图中的绑定问题



我有一个奇怪的绑定问题,我不明白:

我有一个名为VirtualizingCollection的自创建列表类型,它继承自IList。它应与ListView绑定。

我以三种不同的方式尝试。以一种方式(我不喜欢它(它有效,其他两种方式不起作用。

我在 MVVM 架构中实现了我的程序,所以我尝试使用视图模型来显示它(参见方式 3(。

方式1(有效(:

XAML 动态资源:

<Style x:Key="lvStyle" TargetType="{x:Type ListView}">
<Setter Property="ListView.ItemsSource" Value="{Binding}"/>
<Setter Property="ListView.View">
...

代码隐藏:

DataContext = new VirtualizingCollection<LinesSummary>(fs, 100);

结果: 数据显示在ListView但 XAML 中所有其他绑定的DataContext都消失了。所以这对我来说是没有选择的。

方式2(不起作用(

XAML 动态资源:

<Style x:Key="lvStyle" TargetType="{x:Type ListView}">
<Setter Property="ListView.ItemsSource" Value="{Binding test}"/>
<Setter Property="ListView.View">
...

代码隐藏:

VirtualizingCollection<LinesSummary> test = new VirtualizingCollection<LinesSummary>(fs, 100);

结果:未检测到输出中的绑定错误,但未显示数据。

方式3(不起作用(

XAML 动态资源

<Style x:Key="lvStyle" TargetType="{x:Type ListView}">
<Setter Property="ListView.ItemsSource" Value="{Binding test}"/>
<Setter Property="ListView.View">
...

代码隐藏:

myViewModel.x(fs)

视图模型:

public VirtualizingCollection<LinesSummary> test { get; set; }
public void x(FileSummarizer fs) 
{
test = new VirtualizingCollection<LinesSummary>(fs, 100);
}

结果:在输出中未检测到绑定错误,但未显示数据。

一种方法确实有效,因为您要在设置视图的数据上下文之前创建test。因此,当解析所有绑定时,数据已经存在。

您的第三种方法不起作用,因为没有任何内容可以通知您的财产test更改。如果要在视图模型的构造函数中设置test,则应在视图中看到一些数据。目前,没有任何内容可以触发有关test属性的绑定更新。你可以这样做:

public void x(FileSummarizer fs) 
{
test = new VirtualizingCollection<LinesSummary>(fs, 100);
// Now you need to raise an event to notify the view.
// This line depends on if you are implementing INotifyPropertyChanged
// on your ViewModel directly or if you are yousing some ViewModel-Base
// class. Here's an example how it could look like:
RaisePropertyChanged("test");
}

另外:正如 Sasha 在评论中提到的,您的VirtualizingCollection也应该实现某种INotifyPropertyChanged以便在集合内容更改时收到通知。

视图模型类应实现 INotifyPropertyChanged 接口,并在设置test属性时引发PropertyChanged事件:

public class ViewModel : INotifyPropertyChanged
{
private VirtualizingCollection<LinesSummary> _test;
public VirtualizingCollection<LinesSummary> test
{
get { return _test; }
set { _test = value; OnPropertyChanged("test");  }
}
public void x(FileSummarizer fs)
{
//set the property, not the field:
test = new VirtualizingCollection<LinesSummary>(fs, 100);
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

XAML:

<Setter Property="ListView.ItemsSource" Value="{Binding test}"/>

相关内容

  • 没有找到相关文章

最新更新