почему на этот вопрос никто не отвечает. В любом случае, я сделаю все возможное, чтобы объяснить вам. Надеюсь, я не опоздал, чтобы ответить на этот вопрос.
В 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.
Надеюсь, это поможет вам !!