当下拉框值发生改变后,若要通知改变内存的值改变,要用到 UpdateSourceTrigger 属性,则这样写:

<DataTemplate>
                                <ctrl:NumComboBoxCtrl Width="50" 
                              mySelectedValue="{Binding stu.Score,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Cursor="Hand"
                            </DataTemplate>

完整代码如下:

<Window x:Class="CustomControl.knowledge.TestCellTemplateWindow"
        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:CustomControl.knowledge"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        xmlns:ctrl="clr-namespace:CustomControl.UserControl"
        mc:Ignorable="d"
        Title="TestCellTemplateWindow" Height="450" Width="800" WindowStartupLocation="CenterOwner"
        x:Name="me">
    <Window.Resources>
        <local:StudentYesNoToBooleanConverter x:Key="yesNoCvt"/>
        <local:DebugDummyConverter x:Key="debugCvt"/>
        <local:GenderColorConverter x:Key="genderCvt"/>
        <Style x:Key="DataGridTextColumnCenterSytle" TargetType="{x:Type TextBlock}">
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="VerticalAlignment" Value="Center" />
        </Style>
        <Style x:Key="GenderDataGridTextColumnCenterSytle" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource DataGridTextColumnCenterSytle}">
            <Setter Property="Cursor" Value="Hand"/>
            <Setter Property="ToolTip" Value="{Binding stu.Gender}"/>
            <Setter Property="Foreground"  Value="{Binding  stu.Gender,Converter={ StaticResource genderCvt}}"/>
        </Style>
        <Style x:Key="ListViewItemStyle" TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource MaterialDesignGridViewItem}">
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
        </Style>
    </Window.Resources>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <DataGrid x:Name="datagrid" AutoGenerateColumns="False"  CanUserSortColumns="True" CanUserAddRows="False"  IsReadOnly="True"
                      LoadingRow="gd_LoadingRow"  Style="{StaticResource MaterialDesignDataGrid}"
                      HorizontalContentAlignment="Left" VerticalContentAlignment="Center"   MouseDoubleClick="datagrid_MouseDoubleClick"
                <DataGrid.Columns>
                    <!--存储每一行的guid-->
                    <DataGridTextColumn  Binding="{Binding ID}"  Visibility="Collapsed"/>
                    <!--序号-->
                    <DataGridTemplateColumn x:Name="Num">
                         <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                    AncestorType=DataGridRow },Path=Header}" FontSize="16" 
                       TextAlignment="Center" Foreground="Black" VerticalAlignment="Center" Style="{StaticResource MaterialDesignHeadline1TextBlock}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <!--复选按钮-->
                    <DataGridCheckBoxColumn  IsReadOnly="False" Binding="{Binding IsValid,UpdateSourceTrigger=PropertyChanged}">
                        <DataGridCheckBoxColumn.HeaderTemplate >
                            <DataTemplate>
                                <CheckBox Click="CheckBox_Click" HorizontalAlignment="Center" 
                                          VerticalAlignment="Center"
                                          Style="{StaticResource MaterialDesignCheckBox}"
                                          ></CheckBox>
                            </DataTemplate>
                        </DataGridCheckBoxColumn.HeaderTemplate>
                        <DataGridCheckBoxColumn.CellStyle >
                            <Style  BasedOn="{StaticResource MaterialDesignDataGridCell }" TargetType="DataGridCell">
                                <Setter Property="CheckBox.VerticalAlignment"  Value="Center"></Setter>
                                <Setter Property="CheckBox.HorizontalAlignment"  Value="Center"></Setter>
                                <Setter Property="CheckBox.Cursor" Value="Hand"/>
                            </Style>
                        </DataGridCheckBoxColumn.CellStyle>
                    </DataGridCheckBoxColumn>
                    <DataGridTextColumn Binding="{Binding stu.UserName}" Width="100" Header="学生名称" HeaderStyle="{StaticResource  MaterialDesignDataGridColumnHeader}" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}"/>
                    <DataGridTextColumn Binding="{Binding stu.Gender}" Width="100" Header="性别" HeaderStyle="{StaticResource MaterialDesignDataGridColumnHeader}"  ElementStyle="{StaticResource GenderDataGridTextColumnCenterSytle}" />
                    <DataGridTextColumn Binding="{Binding stu.ClassName}" Width="100" Header="班级名称" HeaderStyle="{StaticResource MaterialDesignDataGridColumnHeader}"  ElementStyle="{StaticResource DataGridTextColumnCenterSytle}"/>
                    <DataGridTextColumn Binding="{Binding stu.Address}" Width="120" Header="地址"  HeaderStyle="{StaticResource MaterialDesignDataGridColumnHeader}" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
                   <!--成绩-->
                    <DataGridTemplateColumn Header="成绩"  HeaderStyle="{StaticResource MaterialDesignDataGridColumnHeader}">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ctrl:NumComboBoxCtrl Width="50" 
                              mySelectedValue="{Binding stu.Score,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Cursor="Hand"
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn  Width="Auto" Header="操作" HeaderStyle="{StaticResource MaterialDesignDataGridColumnHeader}">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate >
                                <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
                                    <Button Content="编辑" Style="{StaticResource MaterialDesignOutlinedButton}"/>
                                    <Button Margin="8 0 0 0" Content="删除" Style="{StaticResource MaterialDesignOutlinedButton}" />
                                </StackPanel>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
                <DataGrid.RowStyle>
                    <Style TargetType="DataGridRow" BasedOn="{StaticResource MaterialDesignDataGridRow}">
                        <Setter Property="IsEnabled" Value="{Binding stu.YesNo,Converter={StaticResource yesNoCvt}}" />
                    </Style>
                </DataGrid.RowStyle>
            </DataGrid>
        </Grid>
        <ListView Grid.Row="1" x:Name="listView"  ItemContainerStyle="{StaticResource ListViewItemStyle}"
            <ListView.View>
                <GridView>
                    <GridViewColumn
        Header="IsChecked"  HeaderContainerStyle="{StaticResource  MaterialDesignOutlinedButton}">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding IsValid}" 
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn
        DisplayMemberBinding="{Binding stu.UserName}"
        Header="UserName"  HeaderContainerStyle="{StaticResource  MaterialDesignOutlinedButton}"/>
                    <GridViewColumn
        DisplayMemberBinding="{Binding stu.Gender}"
        Header="Gender" HeaderContainerStyle="{StaticResource  MaterialDesignOutlinedButton}"/>
                    <GridViewColumn
        DisplayMemberBinding="{Binding stu.ClassName}"
        Header="ClassName"  HeaderContainerStyle="{StaticResource  MaterialDesignOutlinedButton}"/>
                    <GridViewColumn
        DisplayMemberBinding="{Binding stu.Score}"
        Header="Score"  HeaderContainerStyle="{StaticResource  MaterialDesignOutlinedButton}"/>
                </GridView>
            </ListView.View>
        </ListView>
        <Button Content="提交" Margin="5" Grid.Row="2" Click="Submit_Click"/>
    </Grid>
</Window>
using CustomControl.Base;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
namespace CustomControl.knowledge
    /// <summary>
    /// TestCellTemplateWindow.xaml 的交互逻辑
    /// </summary>
    public partial class TestCellTemplateWindow : Window
        public TestCellTemplateWindow()
            InitializeComponent();
            students.Add(
                new BasicInfo() { stu = new Student() { UserName = "小王", ClassName = "高二三班", Address = "广州市", Gender = "男",YesNo=1 },ID="111235991" }
            students.Add(
             new BasicInfo() { stu = new Student() { UserName = "小李", ClassName = "高三六班", Address = "清远市", Gender = "女", YesNo = 2 }, ID = "112236992" }
            students.Add(
             new BasicInfo() { stu = new Student() { UserName = "小张", ClassName = "高一一班", Address = "深圳市", Gender = "女", YesNo = 1 }, ID = "113237994" }
            students.Add(
             new BasicInfo() { stu = new Student() { UserName = "小黑", ClassName = "高一三班", Address = "赣州市", Gender = "男", YesNo = 2 }, ID = "114238996" }
            datagrid.ItemsSource = students;
            listView.ItemsSource = students;
        private ObservableCollection<BasicInfo> students = new ObservableCollection<BasicInfo>();
        /// <summary>
        /// 全选
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckBox_Click(object sender, RoutedEventArgs e)
            CheckBox headercb = (CheckBox)sender;
            for (int i = 0; i < datagrid.Items.Count; i++)
                //获取行
                DataGridRow neddrow = (DataGridRow)datagrid.ItemContainerGenerator.ContainerFromIndex(i);
                //获取该行的某列
                CheckBox cb = (CheckBox)datagrid.Columns[2].GetCellContent(neddrow);
                IDataGridListRow info =(IDataGridListRow) datagrid.Columns[2].GetCellContent(neddrow).DataContext;
                bool isEnable = neddrow.IsEnabled;
                if (isEnable)
                    cb.IsChecked = headercb.IsChecked;
                    info.IsValid= (bool)headercb.IsChecked;
        /// <summary>
        /// 加载每一行的索引
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gd_LoadingRow(object sender, DataGridRowEventArgs e)
            e.Row.Header = e.Row.GetIndex() + 1;
        /// <summary>
        /// 提交
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Submit_Click(object sender, RoutedEventArgs e)
            for (int i = 0; i < datagrid.Items.Count; i++)
                //获取行
                DataGridRow neddrow = (DataGridRow)datagrid.ItemContainerGenerator.ContainerFromIndex(i);
                bool isEnable = neddrow.IsEnabled;
                IDataGridListRow info = (IDataGridListRow)datagrid.Columns[1].GetCellContent(neddrow).DataContext;
                string isVaild = info.IsValid.ToString();
                string id = info.ID.ToString();
                MessageBox.Show("iSValid: " + isVaild + "\nid : " + id+"\n isEnable: " +
                    ""+isEnable.ToString());
        /// <summary>
        /// 行双击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void datagrid_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
            DataGrid datagrid = sender as DataGrid;
            IDataGridListRow cellValue =(IDataGridListRow) datagrid.SelectedValue;
            if (cellValue == null) return;
            MessageBox.Show("ID: " + cellValue.ID.ToString());
    #region  Converter
    /// <summary>
    /// 列表性别字段的颜色:
    /// 男:blue,女:pink,其他:不变化
    /// 注:单向转换
    /// </summary>
    public class GenderColorConverter : IValueConverter
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            if (value != null)
                if (!string.IsNullOrWhiteSpace(value.ToString()))
                    string gender = value.ToString().Trim();
                    if ("男".Equals(gender))
                        return new System.Windows.Media.SolidColorBrush(Colors.Blue);
                    else if ("女".Equals(gender))
                        return new SolidColorBrush(Colors.DeepPink);
            return new SolidColorBrush(Colors.Black);
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            return value;
    /// <summary>
    /// 是否禁用转换器
    /// 默认启用
    /// 注:单向转换
    /// </summary>
    public class StudentYesNoToBooleanConverter : IValueConverter
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            if (value != null)
                if (string.IsNullOrWhiteSpace(value.ToString()))
                    return true;
                YesNo yn = (YesNo)Enum.Parse(typeof(YesNo), value.ToString());
                return yn != YesNo.是;
            return true;
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            return value;
    /// <summary>
    /// 用于调试
    /// </summary>
    public class DebugDummyConverter : IValueConverter
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            Debugger.Break();
            return value;
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            Debugger.Break();
            return value;
    /// <summary>
    /// 某行是否可以编辑 --枚举
    /// </summary>
    public enum YesNo
        是 = 1,
        否 = 2
    #endregion
    #region Model
    public class BasicInfo:DataGridListRowBase
       public Student stu { get; set; }
    public class Student: ViewModelBase
        #region  private  fields
        private float score = 10;
        #endregion
        #region public  property
        public string UserName { get; set; }
        public string ClassName { get; set; }
        public string Address { get; set; }
        public string Gender { get; set; } = "未说明";
        public int YesNo { get; set; }
        public float Score
            get => score;
            set => SetProperty(ref score, value);
        #endregion  
    public class DataGridListRowBase : ViewModelBase, IDataGridListRow
        #region private fields
        private string id;
        private bool isValid=true;
        #endregion
        #region public  property
        /// <summary>
        /// 列表主键ID
        /// </summary>
        public string ID { get=>id; set=> SetProperty(ref id, value); }
        /// <summary>
        /// 是否选择
        /// </summary>
        public bool IsValid { get => isValid;set=> SetProperty(ref isValid, value);}
        #endregion
    public interface IDataGridListRow
        /// <summary>
        /// 列表主键ID
        /// </summary>
        string ID { get; set; }
        /// <summary>
        /// 是否选择
        /// </summary>
        bool IsValid { get; set; }
    #endregion
<UserControl x:Class="CustomControl.UserControl.NumComboBoxCtrl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:CustomControl.UserControl"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800" x:Name="me">
    <UserControl.Resources>
        <Style x:Key="myComboBox" TargetType="ComboBox" BasedOn="{StaticResource MaterialDesignComboBox}">
        </Style>
    </UserControl.Resources>
        <ComboBox x:Name="comboBox" 
                  SelectedValue="{Binding ElementName=me ,Path=mySelectedValue}" 
                  Style="{StaticResource myComboBox}" />
    </Grid>
</UserControl>
using System.Collections.Generic;
using System.Windows;
namespace CustomControl.UserControl
    /// <summary>
    /// NumComboBoxCtrl.xaml 的交互逻辑
    /// </summary>
    public partial class NumComboBoxCtrl : System.Windows.Controls.UserControl
        public NumComboBoxCtrl()
            InitializeComponent();
            double item = 0;
            for (int i = 0; i <= 200; i++)
                list.Add(item.ToString());
                item = item + 0.5;
            this.comboBox.ItemsSource = list;
        private List<string> list = new List<string>();
        public string mySelectedValue
            get { return (string)GetValue(mySelectedValueProperty); }
            set { SetValue(mySelectedValueProperty, value); }
        // Using a DependencyProperty as the backing store for mySelectedValue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty mySelectedValueProperty =
            DependencyProperty.Register("mySelectedValue", typeof(string), typeof(NumComboBoxCtrl), new PropertyMetadata("0"));
 public abstract class ViewModelBase : INotifyPropertyChanged
            public event PropertyChangedEventHandler PropertyChanged;
            protected bool SetProperty<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null)
                if (!EqualityComparer<T>.Default.Equals(field, newValue))
                    field = newValue;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
                    return true;
                return false;
                                    以下代码实现了DataGrid的简单绑定List数据源
重点要提一下的是,绑定List数据源,但是不能直接用List。比如下面的代码,使用List&lt;GridItem&gt;只能实现数据修改的绑定,但是数据添加,删除都无法实现双向绑定。所以这里要改用ObservableCollection&lt;GridItem&gt;,其他代码都不用改。只要类型改下即可,WPF内部已经实现了添加,删除等的...
 private void dataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
          e.Cancel = true;
原理就是单元格编辑事件:CellBeginEdit(编辑之前发生),当要编辑时取消该事件,达到禁止编辑的目的
二、禁止编辑
  private void dataGridView_BeginEdit(object sender, 
  public ObservableCollection&lt;object&gt; ObservableObj;        public MainWindow()        {            InitializeComponent();            ObservableObj = new ObservableCollecti...
                                    private void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
      //我DataGrid绑定的是List<PracticeInfo>
      //每个Item则是一个PracticeInfo对象
      //根据自己绑定的对象进修改
      PracticeInfo p...
<DataGrid x:Name="dataGrid" AutoGenerateColumns="False" FontSize="14" RowHeaderWidth="40"
SelectionMode="Single" CanUserAddRows="False" ItemsSource="{Binding}" LoadingR...
{BindingBB,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}
转载于:https://www.cnblogs.com/Mindy-hym/p/11431069.html...
                                    <DataGridTemplateColumn Header="厚度数据" Width="*">
            <DataGridTemplateColumn.CellTemplate>
              <DataTemplate>
                                    1)在FrameworkElement类下有两个重要的属性。利用这两个属性,可以实现UI数据直接与后台的类进绑定2)前端UI界面属性值等动态与后台绑定的方式有多种,此处列出后台设置DataContext以及前端设置DataContext的两种方式,以及数据双向绑定的最佳实践纯前端的方式好处在于,编译一下,就可以在设计阶段看到效果。
1)先定义好我们的类
2)在前端按照步骤引入
后台设置DataContext
在设计阶段是看不到效果的,但是灵活性更高,属性值不用写死
1)定义一个类
2)在当前窗口加载时,进
	Detailed change notification: Unlike otherDependencyObjectobjects, aFreezableobject provides change notifications when sub-property values change.
大意就是和其他的DependencyObject相比,在子属性值更改时,Freezable对象提供更改通知。个人认为应...