简体   繁体   English

更改ObservableCollection后,如何更改ListView的标头内容?

[英]How do I change header content of a ListView after ObservableCollection is changed?

I have a ListView with a grouping using a CollectionViewSource . 我有一个使用CollectionViewSource进行分组的ListView The items from ObservableCollection are grouped by date. ObservableCollection中的项目按日期分组。 I have a button in the group headers, which adds a new record with it's group date. 我在组标题中有一个按钮,它添加了一个新记录及其组日期。 I need to show this button only if there's less than 4 records in this group, or if an item from a group has a one of specific Enum values on a property. 仅当该组中的记录少于4条,或者某个组中的某项在属性上具有特定的Enum值之一时,才需要显示此按钮。

I've made a "filter" using Visibity property and a custom converter of IMultiValueConverter . 我使用Visibity属性和Visibity的自定义转换器IMultiValueConverter了一个“过滤器”。 The Problem is that the check happens only on the ListView initialization and doesn't occur after adding or editing items in the ObservableCollection . 问题是检查仅在ListView初始化上进行,而在ObservableCollection添加或编辑项目后才进行检查。 How do I call Visibility check after collection change? 更改集合后如何调用可见性检查? Or maybe there's more optimized solution for my task? 也许有针对我的任务的更优化的解决方案?

View 视图

<Page.Resources>
    <CollectionViewSource x:Key='src' 
                  Source="{Binding TimesheetEntries}"
                          >
        <CollectionViewSource.SortDescriptions>
            <!--This will sort groups-->
            <componentmodel:SortDescription PropertyName="Date" />
        </CollectionViewSource.SortDescriptions>
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="Date" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
</Page.Resources>
<StackPanel x:Name="MainStackPanel" Orientation="Vertical">
<ListView 
        x:Name="TimesheetEntriesListView"
        Margin="10"
        Grid.Row="1"
        Grid.ColumnSpan="2"
        ItemsSource="{Binding Source={StaticResource src}}"
        SelectedItem="{Binding SelectedEntry, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        >
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Height="30" Margin="3" IsEnabled="{Binding IsEditable}">
                    <ComboBox 
                        SelectedValuePath="Key" DisplayMemberPath="Value" 
                        ItemsSource="{Binding EmploymentTypesDictionary, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                        SelectedValue="{Binding SelectedEmployment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                        Width="300"/>
                    <TextBox 
                        Text="{Binding Hours, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, StringFormat=N2}" 
                        Margin="5,0,0,0"
                        Height="Auto"
                        IsEnabled="{Binding HoursAvaliable}"
                        Width="70"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Margin="5,5,5,0" Orientation="Horizontal">
                            <Button Margin="5,0,10,0" 
                                    Content="+"
                                    Command="{Binding Path=DataContext.AddNewTimesheetEntryCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"
                                    CommandParameter="{Binding Path=Name}"
                                    >
                                <Button.Visibility>
                                    <MultiBinding Converter="{tools:TimesheetListToVisibilityConverter}">
                                        <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}" Path="DataContext.TimesheetEntries"/>
                                        <Binding Path="Name" />
                                    </MultiBinding>
                                </Button.Visibility>
                            </Button>
                            <TextBlock  FontSize="14" Text="{Binding Path=Name, StringFormat='{}{0:dd/MM/yyyy, dddd}'}"/>
                        </StackPanel>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ListView.GroupStyle>
    </ListView>
</StackPanel>

TimesheetListToVisibilityConverter TimesheetListToVisibilityConverter

public class TimesheetListToVisibilityConverter : MarkupExtension, IMultiValueConverter
{
    public TimesheetListToVisibilityConverter()
    {
        TrueValue = Visibility.Visible;
        FalseValue = Visibility.Collapsed;
    }


    public Visibility TrueValue { get; set; }
    public Visibility FalseValue { get; set; }
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        ObservableCollection<TimesheetEntryEntity> val = values[0] as ObservableCollection<TimesheetEntryEntity>;
        DateTime Date;
        bool AddingIsAllowed = false;
        if (values[1] != null)
        {
            Date = (DateTime)values[1];
        } else
        {
            throw new Exception("Дата группы записей была пустой");
        }
        var CurrentDateEntries = val.Where(x => x.Date == Date).ToList();

        if (CurrentDateEntries.Count >= 4)
        {
            return FalseValue;
        }
        foreach (var item in CurrentDateEntries)
        {
            if ((int)item.SelectedEmployment >= 5 && (int)item.SelectedEmployment <= 12)
                return FalseValue;
        }
        return true;
    }
    public object[] ConvertBack(
        object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

Bind to a property that is set when you add items to the source collection, like for example the Items.Count property of the ListView : 绑定到将项目添加到源集合时设置的属性,例如ListViewItems.Count属性:

<Button.Visibility>
    <MultiBinding Converter="{tools:TimesheetListToVisibilityConverter}">
        <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}" Path="DataContext.TimesheetEntries"/>
        <Binding Path="Name" />
        <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}" Path="Items.Count"/>
    </MultiBinding>
</Button.Visibility>

If you also want to converter to get invoked when a property of an individual item changes, you need to detect when this happens and explicitly raise a change notification for any of the data-bound properties. 如果还希望在单个项目的属性更改时调用转换器,则需要检测何时发生这种情况,并显式引发任何数据绑定属性的更改通知。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 ListView 的内容设置为新的 ObservableCollection? - How do I set the content of a ListView to a new ObservableCollection? 更改ObservableCollection后ListView不更新 - ListView not updating after ObservableCollection is changed 如何通过单击标题对带有ObservableCollection的ListView进行排序 - How to sort ListView With ObservableCollection by Clicking Header 如何还原ObservableCollection的更改值? - How can I restore the changed value of an ObservableCollection? 如何获取列表视图的标题高度 - How do I get the header height of a Listview 将ObservableCollection绑定到listView - 存在行,但没有内容 - Binding ObservableCollection to listView - rows are there, but no content 如何将ObservableCollection绑定到ListView? - How to bind ObservableCollection to ListView? 将新项目添加到 ObservableCollection 后,ListView 不会立即更新 - ListView does not update immediately after I add a new item to the ObservableCollection 在列表视图上拖放后如何在代码中更新ObservableCollection-WPF MVVM - How to update ObservableCollection in codeBehind after drag and drop on listview - WPF MVVM 如何在 ObservableCollection 上引发 CollectionChanged 事件,并将更改的项目传递给它? - How can I raise a CollectionChanged event on an ObservableCollection, and pass it the changed items?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM