C# MVVM中ComboBox绑定异常:选中值无法传递至关机命令
Hey, let's figure out why your selected ComboBox values aren't making it to your shutdown command! I spotted a couple key issues in your code, starting with the most critical one:
1. Case Mismatch in Binding Property Names
WPF binding is case-sensitive, and this is where your main problem lies. In your XAML, you're binding SelectedValue to lowercase-starting properties selectedHours and selectedMinutes, but your ViewModel defines uppercase-starting properties SelectedHours and SelectedMinutes. These don't match, so the selected values never sync to your ViewModel.
Fix the XAML Binding:
<!-- Updated Hours ComboBox --> <ComboBox x:Name="HoursCB" Margin="5" Width="40" ItemsSource="{Binding myHours}" SelectedValue="{Binding SelectedHours, UpdateSourceTrigger=PropertyChanged}" /> <!-- Updated Minutes ComboBox --> <ComboBox x:Name="MinutesCB" Margin="5" Width="40" ItemsSource="{Binding myMinutes}" SelectedValue="{Binding SelectedMinutes, UpdateSourceTrigger=PropertyChanged}" />
2. Verify DataContext is Set
Another common gotcha: if you haven't set the DataContext of your MainWindow to your ViewModel, none of your bindings will work at all. Add this to your MainWindow constructor:
public MainWindow() { InitializeComponent(); // Link the View to its ViewModel DataContext = new MainWindowViewModel(); }
3. Command Implementation Improvements
Your command works, but we can make it cleaner and more maintainable:
- Rename
AddNameCommandto something semantic likeStartShutdownCommand(it has nothing to do with adding names!) - Use
CommandManager.RequerySuggestedforCanExecuteChangedinstead of manually subscribing toPropertyChanged—this is the standard WPF approach.
Updated Command Code:
class StartShutdownCommand : ICommand { private readonly MainWindowViewModel _parent; public StartShutdownCommand(MainWindowViewModel parent) { _parent = parent; } // Let WPF handle command revalidation automatically public event EventHandler CanExecuteChanged { add => CommandManager.RequerySuggested += value; remove => CommandManager.RequerySuggested -= value; } public bool CanExecute(object parameter) => true; public void Execute(object parameter) { int totalSeconds = _parent.SelectedHours * 3600 + _parent.SelectedMinutes * 60; MessageBox.Show($"Shutting down the computer in {totalSeconds} seconds!"); // Uncomment when ready to test: // Process.Start("shutdown", $"/s /t {totalSeconds}"); } }
4. Debugging Binding Issues (For Future Troubleshooting)
If you ever run into binding problems again, enable WPF binding tracing to see errors in the Visual Studio Output window. Add this to your App.xaml:
<Application.Resources> <Style TargetType="Binding"> <Setter Property="PresentationTraceSources.TraceLevel" Value="High"/> </Style> </Application.Resources>
This will log any binding failures, making it easy to spot typos or missing properties.
内容的提问来源于stack exchange,提问作者Igor Bieńkowski

