WPF DataGrid每行ComboBox独立绑定问题求助
问题分析与解决方案
这个问题我之前也碰到过,核心原因很明确:你现在把所有行的ComboBox选中值都绑定到了ViewModel里的全局属性selectedMatrice和selectedWeeks,相当于所有行共用同一个变量,改一行自然全变。要实现每行独立选择,得把选中状态放到每行对应的Agent模型里,具体步骤如下:
第一步:修改Agent模型,添加行级选中属性
首先要给你的Agent类新增两个属性,用来存储当前行的选中值,同时确保类实现INotifyPropertyChanged接口(保证绑定的双向更新):
public class Agent : INotifyPropertyChanged { // 保留你已有的属性:Matricule, Nom, Prenom, IsSelected, DateDebut, DateFin... // 当前Agent选中的Matrice private Matrix _selectedMatrice; public Matrix SelectedMatrice { get => _selectedMatrice; set { if (_selectedMatrice != value) { _selectedMatrice = value; OnPropertyChanged(nameof(SelectedMatrice)); } } } // 当前Agent选中的周次 private Matrix _selectedWeek; public Matrix SelectedWeek { get => _selectedWeek; set { if (_selectedWeek != value) { _selectedWeek = value; OnPropertyChanged(nameof(SelectedWeek)); } } } // 当前Agent对应的周次选项列表 private ObservableCollection<Matrix> _matriceWeeks; public ObservableCollection<Matrix> MatriceWeeks { get => _matriceWeeks; set { if (_matriceWeeks != value) { _matriceWeeks = value; OnPropertyChanged(nameof(MatriceWeeks)); } } } // INotifyPropertyChanged接口实现 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
第二步:修改XAML绑定,指向Agent行级属性
把原来绑定到全局ViewModel的selectedMatrice/selectedWeeks,改成绑定到当前行Agent的对应属性:
1. 修改Matrice列的ComboBox
<DataGridTemplateColumn Header="Matrice" Width="150" HeaderStyle="{StaticResource CenterGridHeaderStyle}"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding Path=DataContext.MatricesEtablissement, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" SelectedItem="{Binding SelectedMatrice, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> <ComboBox.ItemTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="A"/> <ColumnDefinition SharedSizeGroup="B"/> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0" Text="{Binding IDMatrice}" Margin="4,0,0,0"/> <TextBlock Grid.Column="1" Text="{Binding Nom}" Margin="4,0,0,0"/> </Grid> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>
2. 修改Semaine列的ComboBox
<DataGridTemplateColumn Header="Semaine" Width="60" HeaderStyle="{StaticResource CenterGridHeaderStyle}"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding MatriceWeeks}" SelectedItem="{Binding SelectedWeek, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Num_jour_sem}" Margin="4,0,0,0"/> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>
第三步:更新ViewModel逻辑,处理行级选项更新
移除ViewModel里的全局selectedMatrice、selectedWeeks、MatriceWeeks属性,改为监听每个Agent的SelectedMatrice变化,动态更新该行的周次选项:
private ObservableCollection<Agent> _agents; public ObservableCollection<Agent> Agents { get => _agents; set { if (_agents != value) { // 取消旧集合的事件订阅 if (_agents != null) { foreach (var agent in _agents) { agent.PropertyChanged -= Agent_PropertyChanged; } } _agents = value; // 订阅新集合中每个Agent的属性变化事件 if (_agents != null) { foreach (var agent in _agents) { agent.PropertyChanged += Agent_PropertyChanged; // 初始化时给Agent设置默认周次列表(如果需要) if (agent.SelectedMatrice != null) { UpdateAgentMatriceWeek(agent); } } } RaisePropertyChanged(nameof(Agents)); } } } // 监听Agent属性变化 private void Agent_PropertyChanged(object sender, PropertyChangedEventArgs e) { var agent = sender as Agent; if (agent == null) return; // 当Agent选中的Matrice变化时,更新其周次选项 if (e.PropertyName == nameof(agent.SelectedMatrice)) { UpdateAgentMatriceWeek(agent); } } // 更新单个Agent的周次选项列表 private void UpdateAgentMatriceWeek(Agent agent) { agent.MatriceWeeks = new ObservableCollection<Matrix>(); if (agent.SelectedMatrice != null) { foreach (Matrix m in Matrices) { if (m.IDMatrice == agent.SelectedMatrice.IDMatrice) { agent.MatriceWeeks.Add(m); } } } }
第四步:获取每行的选择数据
现在直接遍历Agents集合,就能拿到每个Agent的独立选择结果:
foreach (var agent in Agents) { Matrix selectedMatrice = agent.SelectedMatrice; Matrix selectedWeek = agent.SelectedWeek; DateTime? startDate = agent.DateDebut; DateTime? endDate = agent.DateFin; // 这里处理你的业务逻辑,比如提交数据等 }
内容的提问来源于stack exchange,提问作者Sephystos
相关产品推荐
相关产品推荐

