Как изменить содержимое заголовка ListView после изменения ObservableCollection? - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть 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 голосов
/ 12 февраля 2019

Привязка к свойству, которое устанавливается при добавлении элементов в исходную коллекцию, например, свойство Items.Count в ListView:

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

Если вы также хотите преобразовать, чтобы получитьВызывается при изменении свойства отдельного элемента, вам необходимо определить, когда это происходит, и явным образом вызвать уведомление об изменении для любого свойства, связанного с данными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...