Как написать места для заявки на бронирование в WPF? - PullRequest
0 голосов
/ 28 сентября 2019

Я сейчас использую это:

<Window.Resources>
    <DataTemplate x:Key="DataTemplate_Level2">
        <Button Content="{Binding}" Height="40" Width="50" Margin="4,4,4,4"/>
    </DataTemplate>

    <DataTemplate x:Key="DataTemplate_Level1">
        <ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource DataTemplate_Level2}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </DataTemplate>
</Window.Resources>

С этим:

        <ItemsControl 
            x:Name="lst" 
            ItemTemplate="{DynamicResource DataTemplate_Level1}"
            ItemsSource="{Binding TopSeats}"/>

Я связываю List > в качестве источника элементов с номерами 0-2.0 для пустых, 1 для выбранных, 2 для забронированных.

    List<List<int?>> topSeats;

    public List<List<int?>> TopSeats
    {
        get => topSeats;
        set
        {
            topSeats = value;
            NotifyPropertyChanged("TopSeats");
        }
    }

Мой интерфейс выглядит следующим образом: введите описание изображения здесь

Когда я нажимаю кнопку, он должен измениться с 0 на 1, и соответствующий элемент в контейнере List > тоже должен измениться.Но я прибыл к кирпичной стене.Я понятия не имею, как сделать так, чтобы при нажатии любой кнопки в контейнере «List >» изменялся правильный элемент.

Возможно ли это как-то без кода позади?

1 Ответ

0 голосов
/ 29 сентября 2019

Это большой процесс, чтобы объяснить все здесь.Но я сделаю все возможное, чтобы дать вам рабочее решение, и надеюсь, что вы сможете прочитать больше о INotifyPropertyChanged, шаблоне MVVM и шаблоне ICommand.

Для простоты я не реализовал здесь ICommand и не использовал щелчок кодачтобы получить выбранные номера мест (Это только для проверки того, могут ли выбранные номера мест получить или нет).

Шаг 1: Я создал класс Model с именем Seat withСледующие свойства, и я реализую интерфейс INotifyPropertyChanged для захвата событий измененных свойств.См. Ниже мой класс Seat.cs.

public class Seat : INotifyPropertyChanged
    {
        private int seatNo;
        private string seatNumber;
        private bool isSelected;

        public int SeatNo
        {
            get { return seatNo; }
            set { seatNo = value; OnPropertyChanged(); }
        }

        public string SeatNumber
        {
            get { return seatNumber; }
            set { seatNumber = value; OnPropertyChanged(); }
        }

        public bool IsSelected
        {
            get { return isSelected; }
            set { isSelected = value; OnPropertyChanged(); }
        }

        public void OnPropertyChanged([CallerMemberName]string popertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(popertyName));
        }

        private void BaseVM_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
        }


        public event PropertyChangedEventHandler PropertyChanged;
    }

Шаг 2: Я изменил шаблон "DataTemplate_Level2" , чтобы иметь CheckBox вместо Button.Потому что я хотел получить выбранное поведение там, где есть CheckBox.Ниже см. Измененный «DataTemplate_Level2»

<DataTemplate x:Key="DataTemplate_Level2" DataType="{x:Type local:Seat}">
            <CheckBox Content="{Binding SeatNumber}" Height="40" Width="50" Margin="4" Style="{StaticResource CheckBoxStyle}"
                      IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>

Шаг 3: Я изменил внешний вид CheckBox.Чтобы он не выглядел как флажок, а выглядел как кнопка (вы все равно можете настроить его, чтобы он выглядел как настоящее место).Ниже см. Мой измененный CheckBoxStyle

<Style x:Key="CheckBoxStyle" TargetType="CheckBox">
            <Setter Property="HorizontalContentAlignment" Value="Center" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type CheckBox}">
                        <Border x:Name="MainBorder" BorderBrush="Red" BorderThickness="1">
                            <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=CheckBox}, Path=Content}"
                                       TextAlignment="Center" VerticalAlignment="Center"/>
                        </Border>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter TargetName="MainBorder" Property="Background" Value="Yellow" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

Шаг 4: Я добавил несколько кнопок и текстового блока в свое окно для проверки выбранных мест (Этот фрагмент кода предназначен только для тестирования).См. Ниже мой остальной xaml.

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
            <RowDefinition />
        </Grid.RowDefinitions>

        <ItemsControl x:Name="lst" ItemTemplate="{DynamicResource DataTemplate_Level1}" ItemsSource="{Binding TopSeatList}"/>

        <Button Content="Get Selected Seat Numbers" Height="40" Width="50" Margin="4,4,4,4" Grid.Row="1" Click="Button_Click"/>

        <TextBlock x:Name="SelectedSeatNumbersTextBlock" Grid.Row="2" />

    </Grid>

Примечание: - Нет изменений для "DataTemplate_Level1" .Следовательно, вы все еще можете копировать и вставлять свои.

Шаг 5: Теперь в моей модели основного окна я добавил список, подобный вашему List и заполнил некоторые фиктивные данные.

      public List<List<Seat>> TopSeatList
        {
            get => topSeatList;
            set
            {
                topSeatList = value;
                OnPropertyChanged("TopSeatList");
            }
        }

Шаг 6: В коде для события Button_Click я сделал, чтобы получить выбранные номера мест и отобразить их в текстовом блоке.

private void Button_Click(object sender, RoutedEventArgs e)
        {
            var selectedSeats = selectSeatsViewModel.TopSeatList.SelectMany(x => x.Where(y => y.IsSelected));
            string selectedSeatNumbers = string.Empty;
            foreach(var seat in selectedSeats)
            {
                selectedSeatNumbers += seat.SeatNumber + "";
            }

            SelectedSeatNumbersTextBlock.Text = selectedSeatNumbers;
        }

Примечание: - Я считаю, что нужно реализовать гораздо лучший подход к событию click выше с помощью команды, чтобы вы могли избежать его записи в коде позади.

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

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