Вот что-то, что примерно делает то, что вы хотите. Определите модель представления для отдельных элементов в раскрывающемся списке (ComboBox
):
public class ChoiceViewModel : ViewModelBase
{
private string _content;
public string Content
{
get => _content;
set => Set(ref _content, value);
}
private bool _isChecked;
public bool IsChecked
{
get => _isChecked;
set => Set(ref _isChecked, value);
}
private bool _isEnabled;
public bool IsEnabled
{
get => _isEnabled;
set => Set(ref _isEnabled, value);
}
}
Класс ViewModelBase
происходит из MVVM Light Toolkit . Он определяет метод Set
, который я использовал выше, который вызывает событие INotifyPropertyChanged
при каждом изменении свойства.
Затем определите модель представления, которая будет содержать список вариантов:
public class ViewModel : ViewModelBase
{
public ViewModel()
{
Choices = new ObservableCollection<ChoiceViewModel>
{
new ChoiceViewModel {Content = "Check to enable the others", IsEnabled = true},
new ChoiceViewModel {Content = "Choice 1", IsEnabled = false},
new ChoiceViewModel {Content = "Choice 2", IsEnabled = false},
new ChoiceViewModel {Content = "Choice 3", IsEnabled = false},
new ChoiceViewModel {Content = "Choice 4", IsEnabled = false},
};
Choices[0].PropertyChanged += (sender, args) =>
{
if (args.PropertyName == nameof(ChoiceViewModel.IsChecked))
{
var choice = (ChoiceViewModel)sender;
for (var i = 1; i < Choices.Count; i++)
Choices[i].IsEnabled = choice.IsChecked;
RaisePropertyChanged(nameof(ChoicesDisplay));
}
};
for (var i = 1; i < Choices.Count; i++)
{
Choices[i].PropertyChanged += (sender, args) =>
{
if (args.PropertyName == nameof(ChoiceViewModel.IsChecked))
RaisePropertyChanged(nameof(ChoicesDisplay));
};
}
}
public ObservableCollection<ChoiceViewModel> Choices { get; }
public string ChoicesDisplay =>
CheckedChoices.Any()
? string.Join(", ", CheckedChoices.Select(x => x.Content))
: "No choices made";
private IEnumerable<ChoiceViewModel> CheckedChoices =>
Choices.Skip(1).Where(x => x.IsChecked);
}
Модель представления обрабатывает включение или отключение других вариантов, когда первый выбор отмечен или не отмечен. Он также обрабатывает обновление дисплея для выбранных вариантов, разделенных запятыми.
В классе Window
(или в любом другом, подходящем для вашей ситуации) установите DataContext
на ViewModel
:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
XAML выглядит так:
<ComboBox
ItemsSource="{Binding Choices}"
Text="{Binding ChoicesDisplay, Mode=OneWay}"
IsEditable="True"
IsReadOnly="True"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox
Content="{Binding Content}"
IsChecked="{Binding IsChecked}"
IsEnabled="{Binding IsEnabled}"
/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Это решение делает то, что вы хотите, но есть некоторые вещи, которые вы можете исправить. Например, даже если флажок отключен (и поэтому вы не можете установить или снять его), вы все равно можете выбрать его в раскрывающемся списке.