我正在使用MVVM设计模式,ListView绑定到ViewModel上的ListCollectionView.我还有几个用于过滤ListView的组合框.当用户从组合框中选择项目时,将针对所选项目筛选ListView.每当我想要在已经过滤的内容之上进行过滤时,它就像从未发生的那样撤消我以前的过滤器.删除过滤器也是如此.删除一个组合框的过滤器将删除所有过滤器并显示原始列表.是否可以在同一个ListCollectionView上拥有多个独立的过滤器?
我做错了什么,或者这根本不受支持?你可以在这里找到我的应用程序的屏幕截图,看看我想要完成什么.这是我的过滤代码......
/// <summary>
/// Filter the list
/// </summary>
/// <param name="filter">Criteria and Item to filter the list</param>
[MediatorMessageSink("FilterList", ParameterType = typeof(FilterItem))]
public void FilterList(FilterItem filter)
{
// Make sure the list can be filtered...
if (Products.CanFilter)
{
// Now filter the list
Products.Filter = delegate(object obj)
{
Product product = obj as Product;
// Make sure there is an object
if (product != null)
{
bool isFiltered = false;
switch (filter.FilterItemName)
{
case "Category":
isFiltered = …Run Code Online (Sandbox Code Playgroud) 我一直在研究如何避免因INotifyCollectionChanged视图模型对事件的强引用而导致的内存泄漏.我正在玩一个ListCollectionView用来查看是否会为我处理它.我认为以下是泄漏记忆,我做错了什么?
var stuff = new ObservableCollection<string>();
while (true)
{
var result = new ListCollectionView(stuff);
// Just to keep make sure that the memory I'm seeing
// isn't waiting to be GC'd
GC.Collect();
}
Run Code Online (Sandbox Code Playgroud) 这些似乎没有做到这一点:
var source = myViewModel.MyListCollectionView.Select(x => x as MyType);
var source = myViewModel.MyListCollectionView.Select<object, MyType>(x => x as MyType);
var source = myViewModel.MyListCollectionView.SourceCollection.Select<object, MyType>(x => x as MyType);
Run Code Online (Sandbox Code Playgroud) 我正在使用MVVM设计模式创建一个WPF TimeCard应用程序,我正在尝试显示用户按天数分组的总和(总)小时数.我有一个ListView,使用以下XAML将所有TimeCard数据分组:
<ListView.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource GroupItemStyle}">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name, StringFormat=\{0:D\}}" FontWeight="Bold"/>
<TextBlock Text=" (" FontWeight="Bold"/>
<!-- This needs to display the sum of the hours -->
<TextBlock Text="{Binding ???}" FontWeight="Bold"/>
<TextBlock Text=" hours)" FontWeight="Bold"/>
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
Run Code Online (Sandbox Code Playgroud)
这甚至可能吗?起初我以为我会创建一个CollectionViewGroup的部分类并添加我自己的属性.但我不确定这是否会奏效.也许有更好的解决方案......任何建议?
我正在尝试将文本框绑定到XAML中已过滤的集合视图的计数.它不会产生任何错误,但也不会产生任何输出.有谁知道如何做到这一点?
以下是我的XAML的一些片段:
<Window.Resources>
<CollectionViewSource x:Key="MyView" Source="{Binding MyBinding}" Filter="MyFilter" />
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)
...
<TextBlock>
<TextBlock.Text>
<Binding Source="{StaticResource MyView}" Path="View.Count"
StringFormat="{}Count: {0:D}" />
</TextBlock.Text>
</TextBlock>
Run Code Online (Sandbox Code Playgroud)
基本上,我正在尝试显示列表中已过滤项目的数量.
我有一个包含10,000个项目的数据库,您可以在应用程序运行时添加和删除.
我有一个ListBox,最多显示100个项目,并支持分页.
您可以对10,000个项目进行筛选和排序,这些项目需要立即反映在列表框中.
我有一个按钮,只要它通过过滤器就随机选择一个项目.
用于此类操作的最佳集合/视图集是什么?
到目前为止,我的第一步是ObservableCollection在数据库中创建一个我们将调用的所有项目MainOC.
然后List通过解析MainOC我们将调用的内容创建与过滤器匹配的所有项目FilteredList.
然后创建一个ListCollectionView基于上面List的前100项.
缺点:
ListCollectionView每次应用排序操作时都必须重新创建.ListCollectionView每次页面时重新创建.ListCollectionView每次更改过滤器时都必须重新创建.ListCollectionView每次添加或删除项目时都必须重新创建MainOC.我错过了更好的方法吗?
例如,我看到您可以将过滤器应用于ListCollectionView.我应该填写ListCollectionView所有10,000件商品吗?但是,我如何限制我ListBox显示的项目数量?
我应该直接对数据库进行过滤和排序吗?我可以FilteredList直接在数据库上构建并创建我的ListCollectionView基础,但这仍然具有上面列出的所有缺点.
寻找您可以提供的任何输入!
如何ListCollectionView.AddNew确定它创建的对象的类型,以及如何影响它?
我有一些类型(Base,DerivedA和DerivedB)的层次结构,目前我的WPF工具包DataGrid创建DerivedA对象(为什么,我不知道 - 可能是因为网格中的几乎所有数据都属于那种类型),但我会喜欢它来创建DerivedB对象.
更新:我已经尝试从中获取新类ListCollectionView并AddNew为其实现一个新方法,现在我几乎就在那里:唯一剩下的问题是在添加新项后,没有添加新的新项占位符,所以我只能添加一个项目.我目前的方法看起来有点像这样:
public class CustomView : ListCollectionView, IEditableCollectionView
{
public CustomView(System.Collections.IList list)
: base(list)
{
}
object IEditableCollectionView.AddNew()
{
DerivedB obj = new DerivedB();
InternalList.Add(obj);
return obj;
}
}
Run Code Online (Sandbox Code Playgroud) <!-- GroupHeaderStyle -->
<Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="False" Margin="15,0,0,0">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ????????????}"/>
<TextBlock Text="-->"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我希望显示它被分组的属性名称.性别 - >男孩; 性别 - >女孩.
public class Test
{
string gender;
public string Gender
{
get { return gender; }
set { gender = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
我应该提供什么????????????? 在上面的xaml?
另外,如果有任何好的书或链接解释分组的内部细节,请告诉我ListCollectionView.
我有一个WPF Datagrid实现自定义排序,它工作正常.我需要将集合中的一些记录锁定到顶部和底部(顶部锁定和底部锁定).因此,当特定记录被Top锁定时,它应该是集合中的第一个记录,而不管所选列的任何值(即我不想对那些被锁定和锁定底部的行进行排序).这是我的自定义排序方法.
private void PerformLineCustomSort(DataGridColumn column)
{
ListSortDirection direction = (column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending;
column.SortDirection = direction;
ListCollectionView listCollectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(Lines);
LineSorter lineSort = new LineSorter(direction, column);
listCollectionView.CustomSort = lineSort;
}
Run Code Online (Sandbox Code Playgroud)
其中LineSorter是我的IComparer实现的自定义排序器类.这很好用.现在我想将Top lock和Bottom lock应用于ListCollectionView.我已经尝试了以上代码,但它没有任何更改(即列表仅基于自定义排序列进行排序).
listCollectionView.SortDescriptions.Add(new SortDescription("TopLock", ListSortDirection.Descending));
listCollectionView.SortDescriptions.Add(new SortDescription("BotLock", ListSortDirection.Ascending));
Run Code Online (Sandbox Code Playgroud)
有没有办法做这种情况或我需要手动删除,然后添加锁定的记录.请建议..
我有一个ListBox和两个ComboBoxes 的视图.当我在中选择一个项目时ListBox,ComboBoxes 的内容/值将根据所选项目的属性值进行刷新.在我的场景中,它ListBox拥有一个客户列表,第一个ComboBox拥有一个国家列表.所选项目是客户的原产国.第二个ComboBox包含城市列表.选定的城市是客户的起源城市.
在ItemsSource第二个的属性ComboBox绑定到一个ListViewCollection基于一ObservableCollection的所有使用过滤器的城市.当国家/地区的选择ListBox发生变化时,我刷新过滤器以仅显示属于所选国家/地区的城市.
我们假设客户A来自新西兰奥克兰,客户B来自加拿大多伦多.当我选择A时,一切正常.第二个ComboBox城市只有新西兰城市,奥克兰被选中.现在我选择B,所选国家现在是加拿大,城市列表只包含加拿大城市,多伦多被选中.如果现在我回到A,新西兰在这些国家/地区被选中,则城市列表仅包含来自新西兰的城市,但未选择奥克兰.
当我调试这个场景时,我注意到当我选择B时,调用ListCollectionView.Refresh()设置最初选择的客户端A上的城市值null(在刷新调用时设置断点,在模型上的城市设置器上设置另一个断点)见下面的代码).
我猜 - 虽然我不是百分百肯定 - 它发生了,因为我对城市有TwoWay约束力,当过滤器将列表更新到加拿大城市时,奥克兰消失,这些信息被送回物业.然后更新为.在某种程度上,这是有道理的.SelectedItemComboBoxnull
我的问题是:我怎样才能避免这种情况发生?如果ItemsSource仅刷新时,如何防止模型上的属性更新?
下面是我的代码(它有点长,虽然我试图使它成为使问题可重现的最小可能代码量):
public class Country
{
public string Name { get; set; }
public IEnumerable<City> Cities { get; set; }
}
public class City
{ …Run Code Online (Sandbox Code Playgroud)