Как прикрепить список к текстовому полю, перекрывая другие элементы - PullRequest
0 голосов
/ 16 марта 2020

Я пытаюсь создать текстовое поле с раскрывающимся списком автозаполнения.

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

Есть ли способ закрепить или выровнять список по низу данного текстового поля, независимо от других элементов в макете?

enter image description here

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="70"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="70"/>
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0" x:Name="txtb_name"></TextBox>


    <Grid Grid.Row="2" VerticalAlignment="Bottom">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Button Grid.Column="0" x:Name="btn_givecancel" Content="Cancel" Height="70" FontSize="18.667" Click="btn_givecancel_Click"/>
        <Button Grid.Column="1" x:Name="btn_giveaccept" Content="Accept" Height="70" FontSize="18.667" Click="btn_giveaccept_Click"/>
    </Grid>
</Grid>

1 Ответ

0 голосов
/ 16 марта 2020

Вот моя реализация:

SuggestTextBox

Имеется конвертер, который принимает Всего возможных автоматических подсказок и количество просмотров:

<local:IntToVisibilityConverter x:Key="IntToVisibilityConverter"/>

Тогда вот форма с элементами управления TextBox, ListBox и Button.

<Grid Margin="50">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TextBox Grid.Row="0" Text="{Binding UserText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DockPanel.Dock="Top"/>
        <ListBox Grid.Row="1" Grid.RowSpan="2" VerticalAlignment="Top" MaxHeight="55" ItemsSource="{Binding SuggestionsFiltered, UpdateSourceTrigger=PropertyChanged}"
                 Canvas.ZIndex="1">
            <ListBox.Visibility>
                <MultiBinding Converter="{StaticResource IntToVisibilityConverter}">
                    <Binding Path="MaxCount"/>
                    <Binding Path="SuggestionsFiltered.Count"/>
                </MultiBinding>
            </ListBox.Visibility>
        </ListBox>

        <StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0 50 0 0">
            <Button Height="20" Width="100">Clear</Button>
            <Button Height="20" Width="100" Margin="10 0 0 0">Accept</Button>
        </StackPanel>

    </Grid>

Наконец, вот мой DataContext:

public class TheDataContext
    {
        public TheDataContext()
        {
            FillData();

            _SuggestionsFiltered = CollectionViewSource.GetDefaultView(_SuggestionSource);
            _SuggestionsFiltered.Filter = obj =>
            {
                var opt = obj as string;
                if (string.IsNullOrEmpty(_UserText) || _UserText.Length == 0)
                    return true;

                return string.Join("", opt.Take(_UserText.Length)) == _UserText;
            };
        }

        private void FillData()
        {
            _SuggestionSource = new List<string>();
            _SuggestionSource.Add("Alpha");
            _SuggestionSource.Add("Alpines");
            _SuggestionSource.Add("Bravo");
            _SuggestionSource.Add("Brood");
            _SuggestionSource.Add("Charlie");
            _SuggestionSource.Add("Charles");
            _SuggestionSource.Add("Charlotte");
        }

        private string _UserText;

        public string UserText
        {
            get => _UserText;
            set
            {
                _UserText = value;
                _SuggestionsFiltered.Refresh();
            }
        }

        private List<string> _SuggestionSource;

        public int MaxCount => _SuggestionSource.Count;

        private ICollectionView _SuggestionsFiltered;

        public ICollectionView SuggestionsFiltered
        {
            get => _SuggestionsFiltered;
        }
    }

Обратите внимание на весь код вокруг ICollectionView. Кроме того, я принудительно установил некоторые поля в xaml, чтобы показать, что Listbox отрисовывается поверх других элементов управления (Courtsey ZIndex).

Если вы возьмете этот код, не забудьте обработать выбранное событие в ListBox, затем установите TextBox Text к этой стоимости. Также скрыть список. Немного жонглирования.

Наконец, вот конвертер, если вам интересно:

public class IntToVisibilityConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            int maxCount = System.Convert.ToInt32(values[0]);
            int count = System.Convert.ToInt32(values[1]);

            if (count > 0 && count != maxCount)
                return Visibility.Visible;
            return Visibility.Collapsed;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...