WPF Datagrid contains ComboBox while display textblock when display and combobox in editing mode
XAML:
<Window x:Class="WpfApplication1.MainWindow" 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:local="clr-namespace:WpfApplication1" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <DataGrid SelectionMode="Single" IsReadOnly="False" AutoGenerateColumns="False" x:Name="dg" ItemsSource="{Binding UsersList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" RowEditEnding="DataGrid_RowEditEnding" CellEditEnding="dg_CellEditEnding"> <DataGrid.Columns> <DataGridTemplateColumn Header="Nation"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding UserNation,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding Source={x:Static local:MainWindow.NationsList}}" SelectedIndex="0" SelectedValue="{Binding UserNation,UpdateSourceTrigger=LostFocus}"/> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> <!--<DataGridComboBoxColumn Header="Nation" SelectedValueBinding="{Binding UserNation}" ItemsSource="{Binding Source={x:Static local:MainWindow.NationsList}}"> <DataGridComboBoxColumn.EditingElementStyle> <Style TargetType="{x:Type ComboBox}"> <EventSetter Event="SelectionChanged" Handler="NationSelectionChanged"/> </Style> </DataGridComboBoxColumn.EditingElementStyle> </DataGridComboBoxColumn>--> <DataGridCheckBoxColumn Header="CanEnglish" IsThreeState="False" Binding="{Binding CanEnglish,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> <DataGridTextColumn Header="Name" Binding="{Binding Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> <!--<DataGridComboBoxColumn Header="Grade" SelectedValueBinding="{Binding UserGrade}" ItemsSource="{Binding Source={x:Static local:MainWindow.GradesList}}"> <DataGridComboBoxColumn.EditingElementStyle> <Style TargetType="{x:Type ComboBox}"> <EventSetter Event="SelectionChanged" Handler="GradeSelectionChanged"/> </Style> </DataGridComboBoxColumn.EditingElementStyle> </DataGridComboBoxColumn>--> <DataGridTemplateColumn Header="Grade"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding UserGrade,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding Source={x:Static local:MainWindow.GradesList}}" SelectedIndex="0" SelectedValue="{Binding UserGrade,UpdateSourceTrigger=LostFocus}"/> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window>
CS:
using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.IO; using System.Collections.ObjectModel; using System.Data; namespace WpfApplication1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public static List<string> GradesList { get; set; } public List<User> UsersList { get; set; } public static List<string> NationsList { get; set; } static MainWindow() { NationsList = new List<string>() { "USA", "UK", "JAPAN" }; GradesList = new List<string>() { "1", "2", "3" }; } public MainWindow() { InitializeComponent(); this.DataContext = this; InitDataSource(); } private void InitDataSource() { UsersList = new List<User>(); string jsonValue = File.ReadAllText("users.log"); UsersList = JsonConvert.DeserializeObject<List<User>>(jsonValue); } public void NationSelectionChanged(object sender,SelectionChangedEventArgs e) { var comboBox = sender as ComboBox; if (comboBox.SelectedItem != null) { var index = dg.SelectedIndex; if(index>0) { var selectedUser = dg.SelectedItem as User; if(selectedUser!=null) { string newNation = (sender as ComboBox).SelectedItem as string; selectedUser.UserNation = newNation; UsersList.RemoveAt(index); UsersList.Insert(index, selectedUser); string json = JsonConvert.SerializeObject(UsersList, Formatting.Indented); File.WriteAllText("users.log", json, Encoding.UTF8); } } } } public void GradeSelectionChanged(object sender, SelectionChangedEventArgs e) { var comboBox = sender as ComboBox; if (comboBox.SelectedItem != null) { var index = dg.SelectedIndex; if (index > 0) { var selectedUser = dg.SelectedItem as User; if (selectedUser != null) { string newGrade = (sender as ComboBox).SelectedItem as string; selectedUser.UserGrade = newGrade; UsersList.RemoveAt(index); UsersList.Insert(index, selectedUser); string json = JsonConvert.SerializeObject(UsersList, Formatting.Indented); File.WriteAllText("users.log", json, Encoding.UTF8); } } } } private void DataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e) { var selectedUser= e.Row.DataContext as User; if(selectedUser!=null) { UpdateUsersList(selectedUser); } } private void dg_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) { var selectedUser = e.Row.Item as User; if(selectedUser!=null) { UpdateUsersList(selectedUser); } } private void UpdateUsersList(User selectedUser) { if(UsersList!=null && UsersList.Any()) { var index = dg.SelectedIndex; if (index >= 0) { var newUser = new User() { UserNation = selectedUser.UserNation, Name = selectedUser.Name, CanEnglish = selectedUser.CanEnglish, UserId = selectedUser.UserId, UserGrade = selectedUser.UserGrade }; UsersList.RemoveAt(index); UsersList.Insert(index, newUser); string json = JsonConvert.SerializeObject(UsersList, Formatting.Indented); File.WriteAllText("users.log", json, Encoding.UTF8); } } } } public class User { public string UserNation { get; set; } public string Name { get; set; } public bool CanEnglish { get; set; } public int UserId { get; set; } public string UserGrade { get; set; } } public class Nation { public string NationName { get; set; } public string Code { get; set; } } public class Grade { public string GradeName { get; set; } public int GradeIndex { get; set; } } }
This is the key role
<DataGridTemplateColumn Header="Grade"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding UserGrade,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding Source={x:Static local:MainWindow.GradesList}}" SelectedIndex="0" SelectedValue="{Binding UserGrade,UpdateSourceTrigger=LostFocus}"/> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现