WPF DataGrid自定義DataGridTemplateColumn.CellTemplate中ComboBox綁值問題


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

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
        {
            get
            {
                return id;
            }
            set
            {
                id = value;
                OnPropertyChanged("ID");
            }
        }
        public string des;
        public string Des
        {
            get
            {
                return des;
            }
            set
            {
                des = value;
                OnPropertyChanged("Des");
            }
        }
        public string name;
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                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>

 

cs:

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;
            }
            else
            {
                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
        {
            get
            {
                return id;
            }
            set
            {
                id = value;
                OnPropertyChanged("ID");
            }
        }
        public string des;
        public string Des
        {
            get
            {
                return des;
            }
            set
            {
                des = value;
                OnPropertyChanged("Des");
            }
        }
        public string name;
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                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
        {
            get
            {
                return itemList;
            }
            set
            {
                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
        {
            get
            {
                return m_Peoples;
            }
            set
            {
                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;
        }
}    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM