在WPF中使用ComboBox选择更改/添加项目

时间:2018-11-15 18:05:08

标签: c# wpf xaml combobox selectionchanged

简单的问题有时可能最困难。我想了解的三件事; 1.允许在组合框中进行选择更改,以帮助填充第二个组合框中的项目。 2.在填充项目之前,清除第二个框中的项目。 3.在第二个框中添加项目。

请注意,此代码适用于我的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 :(得分:0)

为什么这个问题没有被任何人回答。无论如何,我会尽力向您解释。希望我不迟于回答这个问题。

在WPF中,我们遵循MVVM模式,因此分为模型,视图和视图模型三部分。 在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类中使用,然后将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,然后通过将Printers PropertyName作为参数发送来引发PropertyChanged事件。

视图,我们可以使用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或selectionchanged更改的事件,但是为了使设计器与代码分离,我们没有直接将其与代码耦合。我的意思是说在后面的代码中写一个选择更改事件,然后我们就没有理由了。有关更多信息,请单击https://www.tutorialspoint.com/mvvm/mvvm_introduction.htm,它将使您对MVVM有更深入的了解。

现在,如果您注意到,当选择更改时,我们已将Command属性绑定到Viewmodel中存在的Command属性,这可以使用Interaction类来实现。

那么我们在xaml顶部将view和viewmodel链接到了哪里。这里,数据上下文绑定到ViewmodelBase类(viewmodel)

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

现在回答您的问题

1)允许在组合框中进行选择更改,以帮助填充第二个组合框中的项目。

将调用selectionChanged事件,该事件将调用ViewModelBase中存在的Command方法并填充打印机属性。

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

现在,由于绑定视图模型以查看该属性的任何更改,因此将在第二个下拉列表中显示。现在,我已经在Printers属性中清除并添加了数据,如果根据文本选择了“ Hospital”,则根据文本选择第一个下拉列表时,会将打印机添加到该属性中,并在第二个下拉列表中显示。

2)在填充项目之前清除第二个框中的项目

在Printers属性中添加数据之前,可通过实例化List清除它,在您的情况下,它可以是任何其他类。现在要确定所选数据是否为Hospital,我们需要使用Command Parameter发送SelectedItem,然后使用ComboBoxItem强制转换“ param”并获取内容。

3)在第二个框中添加项目。

我们确定确实在“打印机”属性中添加了值。

希望这对您有帮助!