我正在使用一个ObservableCollection带有两个ICollectionView不同的过滤器.
一种用于按某种类型过滤消息,一种用于计算已检查的消息.正如您所看到的,消息过滤器和消息计数工作正常,但是当我取消检查时,消息将从列表中消失(计数仍然有效).
对于这篇长篇文章,我很抱歉,我想包括所有相关内容.
XAML代码:
<!-- Messages List -->
<DockPanel Grid.Row="1"
           Grid.Column="0"
           Grid.ColumnSpan="3"
           Height="500">
  <ListBox Name="listBoxZone"
           ItemsSource="{Binding filteredMessageList}"
           Background="Transparent"
           BorderThickness="0">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <CheckBox Name="CheckBoxZone"
                  Content="{Binding text}"
                  Tag="{Binding id}"
                  Unchecked="CheckBoxZone_Unchecked"
                  Foreground="WhiteSmoke"
                  Margin="0,5,0,0"
                  IsChecked="{Binding isChecked}" />
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</DockPanel>
<Button Content="Test Add New"
        Grid.Column="2"
        Height="25"
        HorizontalAlignment="Left"
        Margin="34,2,0,0"
        Click="button1_Click" />
<Label Content="{Binding checkedMessageList.Count}"
       Grid.Column="2"
       Height="25"
       Margin="147,2,373,0"
       Width="20"
       Foreground="white" />
截图:

码:
/* ViewModel Class */
public class MainViewModel : INotifyPropertyChanged
{
    // Constructor
    public MainViewModel()
    {
        #region …c# wpf observablecollection collectionviewsource icollectionview
ObservableCollection为每个对它们执行的操作发出通知.首先,他们没有批量添加或删除调用,其次他们不是线程安全的.
这不会让他们变慢吗?我们有更快的选择吗?有人说ICollectionView缠得ObservableCollection很快?这种说法有多正确.
我有一个ObservableCollection和一个WPF UserControl是Databound.Control是一个图表,显示ObservableCollection中每个BarData类型项的垂直条.
ObservableCollection<BarData>
class BarData
{
   public DateTime StartDate {get; set;}
   public double MoneySpent {get; set;}
   public double TotalMoneySpentTillThisBar {get; set;}
}
现在我想基于StartDate对ObservableCollection进行排序,以便BarData将在集合中按StartDate的顺序递增.然后我可以像这样计算每个BarData中TotalMoneySpentTillThisBar的值 -
var collection = new ObservableCollection<BarData>();
//add few BarData objects to collection
collection.Sort(bar => bar.StartData);    // this is ideally the kind of function I was looking for which does not exist 
double total = 0.0;
collection.ToList().ForEach(bar => {
                                     bar.TotalMoneySpentTillThisBar = total + bar.MoneySpent;
                                     total = bar.TotalMoneySpentTillThisBar; 
                                   }
                            );
我知道我可以使用ICollectionView对数据进行排序,过滤数据但不会改变实际的集合.我需要对实际集合进行排序,以便我可以为每个项目计算TotalMoneySpentTillThisBar.它的价值取决于集合中的项目顺序.
谢谢.
是否有任何方法可以自动更新过滤器,ICollectionView而无需Refresh()在进行相关更改时进行调用?
我有以下内容:
[Notify]
public ICollectionView Workers { get; set; }
此属性中的[Notify]属性刚刚实现,INotifyPropertyChanged但在这种情况下它似乎没有做任何事情.
Workers = new CollectionViewSource { Source = DataManager.Data.Workers }.View;
Workers.Filter = w =>
    {
        Worker worker = w as Worker;
        if (w == null)
            return false;
        return worker.Employer == this;
    };
在XAML中:
<TextBlock x:Name="WorkersTextBlock"
           DataContext="{Binding PlayerGuild}"
           FontFamily="Pericles"
           Text="{Binding Workers.Count,
                          StringFormat=Workers : {0},
                          FallbackValue=Workers : 99}" />
更新:看起来使用ICollectionView对我来说是必要的,所以我想重新审视这个主题.我正在为这个问题添加一笔赏金,其收件人将是任何能够提供有关如何实现ICollectionView不需要手动刷新的"不干涉"的洞察力的人.在这一点上,我对任何想法持开放态度.
任何人都可以帮我正确实现ICollectionViewLiveShaping过滤目的吗?关于这个问题,我没有在网上找到很多有用的文档.这就是我所拥有的:
public ICollectionView WorkersEmployed { get; set; }
WorkersEmployed = new CollectionViewSource { Source = GameContainer.Game.Workers }.View;
我没有使用,GetDefaultView因为我需要在此集合上有多个过滤器实例.如果重要,那GameContainer.Game.Workers就是ObservableCollection.
ApplyFilter(WorkersEmployed);
private void ApplyFilter(ICollectionView collectionView)
{
    collectionView.Filter = IsWorkerEmployed;
}
public bool IsWorkerEmployed(object item)
{
    Worker w = item as Worker;
    return w.EmployerID == this.ID;
}
这一切都有效,但当然必须手动刷新,这就是我尝试使用的原因ICollectionViewLiveShaping.我能找到的最好的例子就是这个,但不幸的是我仍然无法让它发挥作用.鉴于我在这里有什么,任何人都可以给我一个正确的方向,让实时过滤工作?
任何帮助将不胜感激.
出于好奇,这真的是一项艰巨的任务吗?如果是这样的话,设计人员似乎ICollectionViewLiveShaping做得很糟糕.
更新:看来,只有这样,才能增加一个属性LiveFilteringProperties的ICollectionViewLiveShaping通过字符串收集.鉴于这种限制,是否可以按另一个类中的属性进行过滤(在本例中为Workers'EmployerID)?
任何有经验的人都能GetDefaultView告诉我,在这种情况下我想做什么甚至是一个可行的选择吗?老实说我不知道是不是因为缺乏文档和可用的例子.即使这是不可行的,也至少知道我是否在浪费时间.
我已经绑定了GridView一个ICollectionView在XAML设计器中的属性未知,因为CollectionView已经转换为类型Object的实体并且无法访问实体属性,它运行良好没有错误但设计者将其显示为错误,如果我绑定到我可以访问属性的集合
示例实体是一个Person具有string Name属性的我将它们放在一个ObservableCollection<Person>并从中获取视图并将其绑定到GridView.ItemsSource现在当我尝试设置列标题DataMemberBinding.FirstName属性时,设计器将其显示为错误
无法在类型对象的数据上下文中解析属性'FirstName'
这是一个错误还是Resharper在我身上耍花招
示例代码:
public class Person 
{
    public string FirstName{
       get { return _firstName; }
       set { SetPropertyValue("FirstName", ref _firstName, value); }
    }
}
public class DataService 
{
    public IDataSource DataContext { get; set; }
    public ICollectionView PersonCollection{ get; set; }
    public DataService()
    {
        DataContext = new DataSource();
        //QueryableCollectionView is from Telerik 
        //but if i use any other CollectionView …我在WPF,.NET 4.0中的DataGrid控件上绑定ICollectionView的属性类型.
我用Filter了ICollectionView.
    public ICollectionView CallsView
    {
        get
        {
            return _callsView;
        }
        set
        {
            _callsView = value;
            NotifyOfPropertyChange(() => CallsView);
        }
    }
    private void FilterCalls()
    {
        if (CallsView != null)
        {
            CallsView.Filter = new Predicate<object>(FilterOut);
            CallsView.Refresh();
        }
    }
    private bool FilterOut(object item)
    {
       //..
    }
Init ICollection视图:
IList<Call> source;
CallsView = CollectionViewSource.GetDefaultView(source);
我试图解决这个问题:
例如,源数据计数为1000个项目.我使用过滤器,在DataGrid控件中我只显示200个项目.
我想将ICollection当前视图转换为IList<Call>
我有一个WPF ListView控件,ItemsSource设置为以这种方式创建的ICollectionView:
var collectionView = 
  System.Windows.Data.CollectionViewSource.GetDefaultView(observableCollection);
this.listView1.ItemsSource = collectionView;
...其中observableCollection是复杂类型的ObservableCollection.ListView配置为为每个项目显示复杂类型上的一个字符串属性.
用户可以刷新ListView,此时我的逻辑存储当前所选项的"键字符串",重新填充底层的observableCollection.然后将先前的排序和过滤器应用于collectionView.此时我想"重新选择"在刷新请求之前选择的项目.observableCollection中的项是新实例,因此我比较各自的字符串属性,然后选择匹配的字符串属性.像这样:
private void SelectThisItem(string value)
{
    foreach (var item in collectionView) // for the ListView in question
    {
        var thing = item as MyComplexType;
        if (thing.StringProperty == value)
        {
            this.listView1.SelectedItem = thing;
            return;
        }
    }
}
这一切都有效.如果选择了第4项,并且用户按下F5,则重构列表,然后选择具有与前4项相同的字符串属性的项.有时这是新的第4项,有时不是,但它提供了" 最不惊讶的行为 ".
当用户随后使用箭头键在ListView中导航时,问题就出现了.刷新后的第一个向上或向下箭头会导致(新)列表视图中的第一个项目被选中,而不管前一个逻辑选择了哪个项目.任何进一步的箭头键按预期工作.
为什么会这样?
这显然违反了"最不惊讶"的规则.我怎么能避免呢?
编辑
 
进一步搜索,这似乎与未答复的
WPF ListView箭头导航和击键问题描述的相同异常,除了我提供更多细节.
当您单击a中的列标题时,这是默认的排序方法DataGrid.当基础列表包含100,000个项目时,刷新视图大约需要20秒.SortDescription在a上设置s 时可以观察到相同的延迟CollectionView.
通过使用ListCollectionView.CustomSort或通过排序和重新分配列表进行排序几乎立即起作用.
为什么会这么拖延?这只是对绑定属性的"反思税"吗?
有些情况下,由于大量的INotifyChangedProperties事件,您有许多UI更新.在这种情况下,您可能只想在批量设置所有属性时仅向UI发出一次更改信号.
我发现这篇很棒的文章解释了如何推迟ViewCollection的刷新:
http://marlongrech.wordpress.com/2008/11/22/icollectionview-explained/
但是当View被推迟时我得到一个例外,我尝试在集合中添加一些东西.我不明白为什么不允许这样做.这就是它的第一点.
InvalidoperationException: 在延迟刷新时无法更改或检查CollectionView的内容或当前位置.
有谁知道如何解决这个问题?非常感谢,