如何使用 Wpf mvvm Enable/Disable 下拉列表中的复选框值并在文本框中显示多选值
How to Enable/Disable checkbox value inside a dropdown and displaying the multiselected value in the text box using Wpf mvvm
请帮助我解决 WPF 中使用 MVVM 的这个问题
我有一个下拉列表,其中有 5 个值。 Onload 下拉列表只需要显示启用第一个值,其余需要 disable.Once i click/check 下拉列表下的第一个复选框需要启用所有其他禁用的复选框值,并且从下拉列表中选择的值需要显示在同一个组合框(多选)中,用逗号或使用 wpf MVVM 架构的任何定界符分隔。
这里有一些东西可以大致满足您的需求。为下拉列表中的各个项目定义视图模型 (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
class来自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
class(或适合您的情况的任何内容)中,将 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>
此解决方案可以满足您的需求,但您可能需要修复一些问题。例如,即使复选框被禁用(因此您无法选中或取消选中它),您仍然可以在下拉列表中选择它。
请帮助我解决 WPF 中使用 MVVM 的这个问题
我有一个下拉列表,其中有 5 个值。 Onload 下拉列表只需要显示启用第一个值,其余需要 disable.Once i click/check 下拉列表下的第一个复选框需要启用所有其他禁用的复选框值,并且从下拉列表中选择的值需要显示在同一个组合框(多选)中,用逗号或使用 wpf MVVM 架构的任何定界符分隔。
这里有一些东西可以大致满足您的需求。为下拉列表中的各个项目定义视图模型 (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
class来自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
class(或适合您的情况的任何内容)中,将 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>
此解决方案可以满足您的需求,但您可能需要修复一些问题。例如,即使复选框被禁用(因此您无法选中或取消选中它),您仍然可以在下拉列表中选择它。