如有不理解的地方请留言。

1.主要解决问题:DataGrid滚动条拉动导致表格数据混乱、数据双向绑定、ComboBox数据源更改后默认显示空值(设置SelectedIndex为0无效

2.解决问题

2.1DataGrid滚动条拉动导致表格数据混乱

将DataGrid中EnableRowVirtualization属性值改为False,不进行动态数据显示。

EnableRowVirtualization="False"

2.2数据双向绑定

1.绑定数据源时设置ComboBox的两个关键属性

ItemsSource="{Binding ItemList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"

2.数据源继承上INotifyPropertyChanged接口,实现接口成员方法,实现当数据源发生变化时通知控件数据源的更新

public class ABC : INotifyPropertyChanged
        public ABC()
        public string id;
        public string ID
                return id;
                id = value;
                OnPropertyChanged("ID");
        public string des;
        public string Des
                return des;
                des = value;
                OnPropertyChanged("Des");
        public string name;
        public string Name
                return name;
                name = value;
                OnPropertyChanged("Name");
        protected internal virtual void OnPropertyChanged(string propertyName)
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        public event PropertyChangedEventHandler PropertyChanged;

2.3ComboBox数据源更改后默认显示空值

ComboBox数据源更新后会执行一遍SelectionChanged事件,这时返回的SelectedIndex为-1,SelectedItem也是null;

解决方法:手动绑定SelectedIndex或SelectedItem值实现跟随数据源变化而变化(需要ComboBox数据源每项必须存在一个是否被选中的属性),我这边用的SelectedIndex。

自定义ComboxSelIndexConverter会在下面cs中贴出。

在window标签中加入:

xmlns:ValueConverter="clr-namespace:WpfTempleate.Converts"

在Window.Resources中加入:

<Window.Resources>
<ValueConverter:ComboxSelIndexConverter x:Key="ComboxSelIndexConverter"/>
</Window.Resources>

ComboBox中加入:

SelectedIndex="{Binding ItemList,Converter={StaticResource ComboxSelIndexConverter},Mode=OneWay}"

 对应的Class->ComboxSelIndexConverter.cs在下面贴出。

3.描述:

xaml->DataGrid

ItemsSource="{Binding People,ElementName=root}"
其中root是当前页面的name值,绑定上下文为当前页面对象,相当于DataContext="{Binding ElementName=root}"
People是DataGrid绑定的数据源(集合)

xaml->ComboBox

ItemsSource="{Binding ItemList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
其中ItemList是ComboBox绑定的数据源(集合)
其中UpdateSourceTrigger=PropertyChanged是表示ComboBox发生变化时触发更新数据源

xaml:

<DataGrid  Width="500" Height="400" x:Name="dataGrid"
                        ScrollViewer.VerticalScrollBarVisibility="Auto"
                        ScrollViewer.HorizontalScrollBarVisibility="Auto"
                        VerticalScrollBarVisibility="Visible"
                        HorizontalScrollBarVisibility="Visible"
                        ItemsSource="{Binding People,ElementName=root}"
                        GridLinesVisibility="All"
                        BorderThickness="1,1,2,1"
                        CanUserDeleteRows="False"
                        CanUserAddRows="False"
                        AutoGenerateColumns="False"
                        EnableRowVirtualization="False">
                <DataGrid.Columns>
                    <DataGridTemplateColumn Header="Operation" IsReadOnly="True" x:Name="abc" >
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate >
                                <StackPanel Orientation="Horizontal">
                      <ComboBox x:Name="comList" IsReadOnly="True" IsEditable="True" Tag="{Binding ID}" HorizontalContentAlignment="Center" SelectionChanged="ComboBox_SelectionChanged" DisplayMemberPath="Name" SelectedValuePath="Value" SelectedIndex="{Binding ItemList,Converter={StaticResource ComboxSelIndexConverter},Mode=OneWay}" ItemsSource="{Binding ItemList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">   </ComboBox>     </StackPanel>         </DataTemplate>         </DataGridTemplateColumn.CellTemplate>         </DataGridTemplateColumn>         </DataGrid.Columns> </DataGrid>
ComboxSelIndexConverter.cs
public class ComboxSelIndexConverter : IValueConverter
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            var abcs = (ObservableCollection<ABC>)value;
            if (abcs == null)
                return -1;
                if (abcs.Count == 0)
                    return -1;
                var abc = abcs.FirstOrDefault(f => f.Des == "1");
                if (abc != null)
                    return abcs.IndexOf(abc);
                return -1;
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            throw new NotImplementedException();

Model数据源模型

 public class ABC : INotifyPropertyChanged
        public ABC()
        public string id;
        public string ID
                return id;
                id = value;
                OnPropertyChanged("ID");
        public string des;
        public string Des
                return des;
                des = value;
                OnPropertyChanged("Des");
        public string name;
        public string Name
                return name;
                name = value;
                OnPropertyChanged("Name");
        protected internal virtual void OnPropertyChanged(string propertyName)
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        public event PropertyChangedEventHandler PropertyChanged;
    public class People : INotifyPropertyChanged
        public People()
            Genre = new Genre();
            ItemList = new ObservableCollection<ABC>(){
                new ABC(){ ID = "1",Name = "AAA",des="1"},
                new ABC(){ ID = "2",Name = "BBB",des="0"}
        public string ID { get; set; }
        public string Name2 { get; set; }
        public string Name { get; set; }
        public string Price { get; set; }
        public ObservableCollection<ABC> itemList;
        public ObservableCollection<ABC> ItemList
                return itemList;
                itemList = value;
                OnPropertyChanged("ItemList");
        public Genre Genre;
        protected internal virtual void OnPropertyChanged(string propertyName)
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        public event PropertyChangedEventHandler PropertyChanged;
    public class Genre
        public string Name { get; set; }

数据源绑定

public partial class MainWindow : Window, INotifyPropertyChanged
        public MainWindow()
            InitializeComponent();
        ObservableCollection<People> m_Peoples = new ObservableCollection<People>();
        public event PropertyChangedEventHandler PropertyChanged;
        protected internal virtual void OnPropertyChanged(string propertyName)
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        public ObservableCollection<People> People
                return m_Peoples;
                m_Peoples = value;
                OnPropertyChanged("People");
       public static ObservableCollection<People> GetPeopleAll()
            ObservableCollection<People> People = new ObservableCollection<People>();
            for (int i = 0; i < 4; i++)
                People.Add(new People() { ID = (i + 1).ToString(), Name = "李四" + (i + 1).ToString(), Name2 = "测试文本" + (i + 1).ToString(), Genre = new Genre() { Name = "张三" + (i + 1).ToString() }, Price = "100" + (i + 1).ToString() });
            return People;
        private void Window_Loaded(object sender, RoutedEventArgs e)
            People = GetPeopleAll();
            dataGrid.DataContext = People;