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

时间:2019-02-12 10:12:43

标签: c# wpf listview mvvm

我有一个ListView,并使用CollectionViewSource进行了分组。 ObservableCollection中的项目按日期分组。我在组标题中有一个按钮,它添加了一个新记录及其组日期。仅当该组中的记录少于4条,或者某个组中的某项在属性上具有特定的Enum值之一时,才需要显示此按钮。

我使用Visibity属性和IMultiValueConverter的自定义转换器创建了一个“过滤器”。问题是,检查仅在ListView初始化时进行,而在ObservableCollection中添加或编辑项目后才进行。更改集合后如何调用可见性检查?也许还有针对我的任务的更优化的解决方案?

查看

<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

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

1 个答案:

答案 0 :(得分:0)

绑定到将项目添加到源集合时设置的属性,例如Items.Count的{​​{1}}属性:

ListView

如果您还希望在单个项目的属性更改时调用转换器,则需要检测何时发生这种情况,并显式引发任何数据绑定属性的更改通知。