Выбор изменить / добавить элементы с помощью ComboBox в WPF - PullRequest
0 голосов
/ 15 ноября 2018

Простые вопросы иногда могут быть самыми сложными. 3 вещи, которые я пытаюсь понять; 1. Разрешить изменение выбора в поле со списком, чтобы помочь заполнить элементы во втором списке. 2. Очистите элементы во 2-й ячейке перед заполнением элементов. 3. Добавление предметов во 2-ю коробку.

Обратите внимание, что этот код работал с моим кодом WinForms, но я пытаюсь преобразовать его в WPF и понять этот код.

Код:

<ComboBox Name="ComboBox_Location" HorizontalAlignment="Left" Margin="170,56,0,0" VerticalAlignment="Top" Width="160">
        <ComboBoxItem Content="Hospital"/>
</ComboBox>
<ComboBox Name="ComboBox_Printer" HorizontalAlignment="Left" Margin="30,131,0,0" VerticalAlignment="Top" Width="300"/>

$ComboBox_Location.add_SelectionChanged{

    switch ($ComboBox_Location.SelectedItem){

        "Hospital"{
            $ComboBox_Printer.Items.Clear();
            $Hospital = Get-Printer -ComputerName \\bmh01-print01 | where {($_.Name -like “*BMH01*”) -and ($_.DeviceType -eq "Print")}
            foreach($Name in $Hospital){
            $ComboBox_Printer.Items.Add("$($Name.name)");
            }
        }
    }

Заранее спасибо! И если у кого-нибудь из вас есть веб-сайт или ссылка, на которую я мог бы перейти, чтобы увидеть конкретную кодировку для WPF, любая помощь будет принята с благодарностью!

1 Ответ

0 голосов
/ 19 ноября 2018

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

В WPF мы следуем шаблону MVVM, так что есть 3 части Model, View и ViewModel. В viewmodel нам нужно унаследовать Icommand и создать CommandHandler, чтобы при наличии каких-либо изменений нажатие кнопки / выборка отправлялось с помощью этой команды и вызывался делегированный обработчик события.

Класс CommandHandler

public class CommandHandler : ICommand
{
    private Action<object> _action;
    private bool _canExeute;
    public event EventHandler CanExecuteChanged;

    private bool canExeute
    {
        set
        {
            _canExeute = value;
            CanExecuteChanged(this, new EventArgs());
        }
    }


    public CommandHandler(Action<object> action,bool canExecute)
    {
        _action = action;
        _canExeute = canExecute;
    } 
    public bool CanExecute(object parameter)
    {
        return _canExeute;
    }

    public void Execute(object parameter)
    {
        _action(parameter);
    }
}

Этот CommandHandler будет использоваться в классе ViewModel, а затем для модели представления будет установлен Datacontext для просмотра через XAML.

   public class ViewModelBase : INotifyPropertyChanged
{
    private List<String> _printer = new List<string>();

    private bool _canExecute;

    public ViewModelBase()
    {
        _canExecute = true;
    }

    public List<string> Printers
    {
        get { return _printer; }
        set { _printer = value; }
    }


    private ICommand _SelectedItemChangedCommand;

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }


    public ICommand SelectedItemChangedCommand
    {
        get
        {
            return _SelectedItemChangedCommand ?? (_SelectedItemChangedCommand =
                       new CommandHandler(obj => SelectedItemChangedHandler(obj), _canExecute));
        }
    }


    public void SelectedItemChangedHandler(object param)
    {
        var selectedItem = ((ComboBoxItem)param).Content;
        switch (selectedItem)
        {
            case "Hospital":
                Printers = new List<string>(); //clearing the list;
                                               // Hospital = GetHospital();// - ComputerName \\bmh01 - print01 | where { ($_.Name - like “*BMH01 *”) -and($_.DeviceType - eq "Print")}

// Here I have added data hard coded, you need to call your method and assgin it to printers property.

                Printers.Add("First Floor Printer");
                Printers.Add("Second Floor Printer");
                OnPropertyChanged(nameof(Printers));
                break;
            default:
                Printers = new List<string>();
               break;
        }
    }


}

Класс ViewModel также наследует INotifyPropertyChanged, где нам нужно реализовать событие и вызвать его. Теперь нам нужно вызвать событие propertychanged, указав имя свойства, которое изменяется с помощью присваивания. Поэтому внутри SelectionChangedCommand мы добавляем Printer, а затем вызываем событие PropertyChanged, отправляя имя_принтера Printers в качестве параметра.

Вид. Мы можем использовать Window или UserControl. Для этого примера я использовал Window.

Вид: -

<Window x:Class="Combo2.MainScreen"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

    xmlns:local="clr-namespace:Combo2"
    xmlns:ViewModel="clr-namespace:Combo2.Validate"
    mc:Ignorable="d"
    x:Name="Window1"
    Title="MainScreen" Height="450" Width="800">
<Window.DataContext>
    <ViewModel:ViewModelBase/>
</Window.DataContext>


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

        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label Content="Location" HorizontalAlignment="Left"  Grid.Row="0" VerticalAlignment="Top" Grid.Column="0"/>
        <ComboBox Name="ComboBox_Location" HorizontalAlignment="Left"   VerticalAlignment="Top" Width="160" Grid.Row="0" Grid.Column="1"  >
            <ComboBoxItem Content="Hospital"/>
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Binding SelectedItemChangedCommand}"  CommandParameter="{Binding ElementName=ComboBox_Location, Path=SelectedItem}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>

        </ComboBox>
        <Label Content="Printer Names" HorizontalAlignment="Left"  Grid.Row="1" VerticalAlignment="Top"  Grid.Column="0"/>
        <ComboBox Name="ComboBox_Printer" HorizontalAlignment="Left"  VerticalAlignment="Top" Width="160"  Grid.Row="1" Grid.Column="1" ItemsSource="{Binding Printers}" >

        </ComboBox>


    </Grid>

Теперь, как и в winform, у нас есть событие click или selection Change, но чтобы отделить дизайнер от кода, мы не связываем его напрямую с ним. Я имею в виду, чтобы написать событие выбора изменилось в коде, тогда мы не оправдываем это. Для получения дополнительной информации нажмите https://www.tutorialspoint.com/mvvm/mvvm_introduction.htm, что даст вам более полное представление о MVVM.

Теперь, если вы заметили, что при изменении выбора мы связали свойство Command со свойством Command, присутствующим в Viewmodel, что возможно с помощью класса Interaction.

Так, где мы связали представление и модель представления, что это наверху xaml? Здесь текстовый текст привязан к классу ViewmodelBase (viewmodel)

<Window.DataContext>
    <ViewModel:ViewModelBase/>
</Window.DataContext>

Теперь ответьте на свой вопрос

1) Разрешить изменение выделения внутри поля со списком, чтобы помочь заполнить элементы во втором поле со списком.

Вызывается событие selectionChanged, которое вызывает метод Command, присутствующий в ViewModelBase, и заполняет свойство Printers.

<i:InvokeCommandAction Command="{Binding SelectedItemChangedCommand}"  CommandParameter="{Binding ElementName=ComboBox_Location, Path=SelectedItem}"/>

Теперь, поскольку модель представления обязана просматривать любые изменения свойства, она отображается во втором раскрывающемся списке. Теперь, когда я очистил и добавил данные в свойстве «Принтеры», при выборе 1-й капли на основе текста, если он соответствует «Больнице», принтеры добавляются в свойство и отображаются во 2-м раскрывающемся списке.

2) Очистить элементы во 2-й ячейке перед заполнением элементов

Прежде чем добавлять данные в свойство Printers, они очищаются путем создания экземпляра List, в вашем случае это может быть любой другой класс. Теперь, чтобы определить, являются ли выбранные данные данными «Больница», нам нужно отправить SelectedItem с помощью параметра «Команда», мы приводим «param» с помощью ComboBoxItem и получаем содержимое.

3) Добавление предметов во 2-й ящик.

Мы уверены, что добавили значения в свойство Printers.

Надеюсь, это поможет вам !!

...