ListView中的绑定问题

时间:2017-08-24 06:41:06

标签: c# wpf listview binding viewmodel

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

我有一个名为VirtualizingCollection的自创名单类型,它继承自IList。它应绑定到ListView

我以三种不同的方式尝试。在某种程度上(我不喜欢它)它起作用,另外两种方式不起作用。

我在MVVM架构中实现了我的程序,因此我尝试使用viewmodel来显示它(参见方法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);

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

Way3(不起作用)

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);
}

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

2 个答案:

答案 0 :(得分:0)

您的第一种方法确实有效,因为您在设置View的DataContext之前创建了test。因此,当所有Bindings得到解决时,数据已经存在。

您的第3种方法不起作用,因为没有任何内容可以通知您查看您的财产test的更改。如果要在ViewModel的构造函数中设置test,您应该在View中看到一些数据。现在,没有任何内容可以触发关于test属性的Binding更新。你可以这样做:

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,以便在收藏集的内容发生变化时通知您的View。

答案 1 :(得分:0)

您的视图模型类应实现http://lists.typo3.org/pipermail/typo3-dev/2009-December/038130.html接口,并在设置getVisualBounds属性时引发PropertyChanged事件:

test

<强> XAML:

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));
    }
}